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此时是不允许改变”,是你误解锁了,锁只是同步方法中的一种标识,表示是否有线程进入同步方法,根本不会影响具体对象。