请帮助解释的多线程的执行顺序问题,先谢谢!synchronized
请解释下以下线程的执行顺序,并且告诉我下,为什么的理解是错误的:
给出两种执行顺序:
1、
thread.start();进去就绪状态---》调用run()方法,走到m1()--->锁定TT,此时b=1000---》进入休眠5秒状态
在sleep过程中,main方法开始执行,TT由于是锁定状态,则main线程不能调用m2()的方法,只有等待thread线程执行完,5秒过后,thread线程执行完,先打印b=1000
然后main线程再调用m2()方法,锁定TT,等待2.5秒以后,设置b的值为200,最后打印tt.b的值为2000
最终显示结果为:
b=1000
2000
2、
thread.start();进去就绪状态---》Main线程执行,调用tt.m2(),TT锁定,m2()方法执行完毕以后才能释放锁,释放锁后thread才能执行m1(),m2休眠2.5秒后,设置b=2000,然后先打印tt.b的值为2000,然后释放锁
然后thread执行m1方法,锁定TT,设置b=1000,等待5秒后,打印b=1000
最终显示结果为:
2000
b=1000
我这边实际的执行结果是
1000
b=1000
1、请解释这是何种逻辑?
2、假如把m2的synchronized关键字去掉,有是一种啥效果?怎么执行的呢?
先谢谢大家!
public class TT implements Runnable{
int b=100;
public synchronized void m1() throws Exception{
b=1000;
Thread.sleep(5000);
System.out.println("b="+b);
}
public synchronized void m2() throws Exception{
Thread.sleep(2500);
b=2000;
}
@Override
public void run() {
try {
m1();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args)throws Exception {
TT tt = new TT();
Thread thread = new Thread(tt);
thread.start();
tt.m2();
System.out.println(tt.b);
}
}
------解决方案--------------------我这边:
有时候打印:
1000
b=1000
有时候打印:
2000
b=1000
------解决方案--------------------程序由主线程调用,当执行到thread.start()后,创建了一个新的的线程,去执行m1()方法
而主线程继续执行,这个时候m2()方法已经调用了。2.5秒后,这个时候m2()方法执行完毕了,
而m1()方法还没完毕,因此此时的时候b仍然等于1000.所以会先输出1000,然后输出b=1000.
这个跟synchronized没关系吧,没有多个线程同时访问同一个方法啊??
如果不清楚的话,可以把m2()方法里面的暂停去掉,这样的话就是LZ猜测的第二种结果了。
------解决方案--------------------运行了几次,结果为
1000
b=1000
或
2000
b=1000
------解决方案--------------------
m2()方法执行完毕后,b不是应该为2000吗
------解决方案--------------------以下仅代表个人观点:
主线程启动了两个线程,由main线程生成了一个thread线程,两个线程虽然没有什么关联关系,但是新线程的启动肯定需要时间,虽然时间很短但是没有main线程直接继续运行来的快,所以是main线程优先进入了m2方法,由于m2方法是synchronized方法,即使thread线程初始化完成了,也要等待锁释放,等main线程的tt.m2();执行完成后,thread线程才可以执行。这时两个线程就并发执行了,如果thread执行的快,就会输出“1000”,否则,就会输出“2000”。但是由于thread线程因为等待了5秒,最后输出的肯定是“b=1000”。
不知道说的清不清楚?
------解决方案--------------------其实就一句话:线程同步问题!
两个线程要是不进行同步,其中指令的执行顺序是不可预期的!
也就是说:结果可能与你预期相同,也可能不同,同或不同,都属于概率事件!
具体而言:你这里用的synchronized关键字,只保证了两个方法不会同时执行,但却无法保证二者到底谁先执行!
从设计者的角度而言,如果两个事件需要顺序发生,那么一般不会将其分派到两个不同线程中执行!否则,需要的同步机制是比较复杂的。
------解决方案--------------------你试的不够多
------解决方案--------------------如果楼主想按顺序来执行的话,可以在run()里面加上m1();m2();或是m2();m1();
像楼主上面的代码那么执行的话,执行结果确实是不可预计的
------解决方案--------------------