JAVA 多线程 synchronized问题

来源:百度知道 编辑:UC知道 时间:2024/07/01 16:39:53
public class TT implements Runnable {
int b = 100;
public synchronized void m1() throws Exception{
b = 1000;
Thread.sleep(1000);
System.out.println("b = " + b);
}
public void m2() {
System.out.println(b);
}
public void run() {
try {
m1();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
TT tt = new TT();
Thread t = new Thread(tt);
t.start();
Thread.sleep(100);
tt.m2();
}
}

运行结果为
1000
b=1000

我的问题是: 如果要在m2的方法上加synchronized
也就是变为public synchronized void m2() throws Exception{
.....
}
为什么输出结果就变了,输出结果为:
b=1000
1000

刚开始m2上没有synchronized,首先线程执行调用run方法执行m1,但是在内部执行了sleep,所以main线程继续执行,故而执行了m2方法,出现了上面的结果
当m2加上synchronized时,m1、m2方法对于同一个实例来说共有一把锁,这里只有tt一个实例,所以m1、m2共同竞争tt的锁,即m1、m2同时只能有一个方法在执行。但执行m1然后sleep时并没有放弃实例锁,所以这时m2无法执行,只能等待m1执行完毕放弃了tt实例的锁时,m2才可以自行
TT tt = new TT();
TT tt2 = new TT();
Thread t = new Thread(tt);
t.start();
Thread.sleep(100);
tt2.m2();
如果改成上面的程序,就会出现第一个结果了,因为有两个实例tt,tt2意味着这里有2把锁,m1、m2不会去竞争同一把锁,各自执行。

...同步只是加锁 控制不了执行顺序 换个环境执行结果可能旧又不一样了

你可以把:
...

t.start();
Thread.sleep(100);
tt.m2();

...
的中间那一句注释掉,看看效果。
自己多试试,会明白规律的。
别人说只是别人的想法,不会加深你的印象。