当前所在位置:珠峰网资料 >> 计算机 >> 计算机等级考试 >> 正文
Java中不同线程调用synchronized方法的问题
发布时间:2010/6/1 9:40:12 来源:城市学习网 编辑:ziteng
  一个含有synchronized修饰符方法的类:
  public class ForTest {
  private int i = 0;
  public synchronized void fun1(){
  i = 100;
  try {
  Thread.sleep(5000);
  } catch (InterruptedException e) {
  e.printStackTrace();
  }
  System.out.println("fun1: i = " + i);
  }
  public void fun2(){
  i = i + 1;
  System.out.println("fun2: i = " + i);
  }
  }
  两个线程类:
  public class MyThread1 implements Runnable {
  private ForTest ft = null;
  public MyThread1(ForTest ft){
  this.ft = ft;
  }
  public void run() {
  ft.fun1();
  }
  } [NextPage]   public class MyThread2 implements Runnable {
  private ForTest ft = null;
  public MyThread2(ForTest ft){
  this.ft = ft;
  }
  public void run() {
  ft.fun2();
  }
  }
  测试的main类:
  public class TestMain {
  public static void main(String[] args) {
  ForTest ft = new ForTest();
  new Thread(new MyThread1(ft)).start();
  new Thread(new MyThread2(ft)).start();
  }
  }
  运行输出结果:
  先输出:fun2: i = 101
  5秒钟后输出:fun1: i = 101
  问题:在main()方法中我启动了两个线程,我个人认为当程序执行到第一个线程MyThread1的run()方法中时,调用了 ft.fun1(),由于方法fun1()是加了synchronized的方法,而且线程1还sleep了5秒钟,所以此时的对象实例ft的锁在5秒内被线程1拥有!然后在这5秒内当第二个线程调用了ft.fun2()时,由于ft此时正被线程1锁定,所以我就感觉代码ft.fun2()应当阻塞,等线程1释放ft的锁后才会执行!但是输出结果和我想象的不一样呀!这是为什么呢?
  还有即使线程2中的ft.fun2()方法在那5秒钟不阻塞,当线程2执行到fun2()中的i = i + 1;时,我认为由于ft对象此时被锁定,所以i此时是不允许改变的,但是事实上是可以改变的,为什么呢?synchronized修饰的方法这么理解呀?
  答:如果你的fun2()也用synchronized ,那么就如你所愿,第二个线程在fun2()中处于阻塞。如果不用synchronized ,那么此处不涉及锁的概念,只是普通的方法,你锁不锁都影响不到它。
  至于“i此时是不允许改变”,是你误解锁了,锁只是同步方法中的一种标识,表示是否有线程进入同步方法,根本不会影响具体对象。
广告合作:400-664-0084 全国热线:400-664-0084
Copyright 2010 - 2017 www.my8848.com 珠峰网 粤ICP备15066211号
珠峰网 版权所有 All Rights Reserved