当前位置: 代码迷 >> 多核软件开发 >> 线程同步有关问题 求高手解答~
  详细解决方案

线程同步有关问题 求高手解答~

热度:1977   发布时间:2013-02-26 00:00:00.0
线程同步问题 求高手解答~~ - Java / Java SE
public synchronized void m1() throws Exception{

b = 4000;
Thread.sleep(5000);
System.out.println("b = " + b);
}

public synchronized void m2() throws Exception {

Thread.sleep(2500);
b = 2000;
//System.out.println("wowo" + 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();

tt.m2();
System.out.println(tt.b);
}
}



没加 System.out.println("wowo" + b); 的是后输出结果是4000 b= 4000

但是加了System.out.println("wowo" + b); 输出结果为什么变得不一样了 wowo2000 2000 b=4000

不太明白 加了这句话后应该没什么影响吧 为什么 中间那个数变了


我的线程理解是 主线程开始执行 然后线程1(这里是执行到sleep后再执行main方法吗), 然后 到线程2 ,线程2执行完后接着执行线程1 , 途中线程1sleep 之后执行System.out.println(tt.b);,接着在执行完线程1. 哪里理解错误了呢?

------解决方案--------------------------------------------------------
第一种情况:之所以你总是看到
4000
b = 4000
是因为你点的次数不够多(我机器上可以看到不同情况):
a:如果t启动的线程先得到调度执行,将b置为4000然后睡眠,main线程有机会得到调度,执行tt.m2(),这里会因为tt的锁被t启动的线程占了而已不能进入m2,一直等到t睡醒,打印b = 4000,然后m2将b置为2000,打印2000
看到
b = 4000
2000
这种情况在我的机器上一直没看到,可以在t.start()后加上t.join(),让t启动的线程执行完了main线程再执行就会看到我说的
b:如果是main线程先得到调度,执行m2,先睡眠,t想进入m1也会因为锁被main占了而不能进入,main醒来把b置为2000,如果还不被切换,打印2000,main结束,t执行,打印b = 4000,如果main执行完tt.m2();后马上被切换,t把b置为4000,然后睡眠,main得到调度,打印4000,然后t睡醒,打印b = 4000

第二种情况自己分析下吧,总之你可以假设在同步块外面任何地方都有可能发生切换,你一时看不到别的结果不代表永远看不到,可以把Thread.sleep()去掉看看~~效果可能明显一些

------解决方案--------------------------------------------------------
tt.m2();
System.out.println(tt.b);同在主线程,输出tt.b再怎样也得等到tt.m2()执行完吧
  相关解决方案