为什么无论睡2500,6000。。。。多久,都是这样?怎么能让b=2000啊?
public class Why implements Runnable{
int b=100;
public synchronized void m1() throws Exception{
b=1000;
Thread.sleep(5000);
System.out.println("m1 of b="+b);
}
public synchronized void m2() throws Exception{
Thread.sleep(6000);
//Thread.sleep(2500);
b=2000;
}
public void run(){
try{
m1();
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String [] args) throws Exception{
Why tt=new Why();
Thread t=new Thread(tt);
t.start();
tt.m2();
System.out.println("main to print b="+tt.b);
}
}
--------
main to print=1000;
m1 of b=1000
????
可以帮我分析执行顺序吗 --------------------编程问答-------------------- 为什么总是先打印main to print --------------------编程问答-------------------- 先执行m1,m1睡眠,回到main中执行m2,m2睡眠,又回到main,所以就先打印main to print
然后5s过去了,执行m1的print
把synchronized关键字去掉应该就可以了 --------------------编程问答-------------------- 个人浅见:
1 t.start(); 启动这个线程,等待虚拟机进行调度。
2 主线程执行m2()方法。因为这个方法加了同步(synchronized), 所以要看是否能得到这个锁。在上面第一步,t线程要等待虚拟机调度,所以一般情况下在m2运行时,m1()尚未运行,同步对象锁是空闲的。
3 主线程m2()方法休眠6秒,因为是在同步方法里,所以不释放锁,(m1())因为得不到锁而继续等待。
4 主线程休眠结束,给b 赋值2000,m2()结束,同步锁释放。
5 主线程接着执行System.out.println("main to print b="+tt.b);语句。输出main to print b=2000 (但有可能没有执行完,步骤6开始了,那样会输出b=1000. 这块由随机性,并不是总输出1000)。
6 线程t马上得到同步锁,开始执行b=1000. 然后休眠。
7 m1 休眠结束,输出m1 of b=1000.
楼主想让b = 2000, 只能是 main to print b=2000,可以在m1()方法里,把b=1000;语句放在休眠之后。 --------------------编程问答-------------------- 下面贴代码请使用代码模板。
public class Why implements Runnable{
int b=100;
public synchronized void m1() throws Exception{
b=1000;
Thread.sleep(5000);
System.out.println("m1 of b="+b);
}
public synchronized void m2() throws Exception{
Thread.sleep(6000);
//Thread.sleep(2500);
b=2000;
}
public void run(){
try{
m1();
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String [] args) throws Exception{
Why tt=new Why();
Thread t=new Thread(tt);
t.start();
tt.m2();
System.out.println("main to print b="+tt.b);
}
}
--------
main to print=1000;
m1 of b=1000
????
可以帮我分析执行顺序吗
这样,别人看的清晰点,也愿意回答。
你这个代码是有可能得到2000的,如果你运行足够多次的话。关键在于,第一次拿到锁的是m1方法还是m2方法,如果第一次运行的是m1方法,那有可能输出2000了,你想要的结果。
你在里面sleep方法睡多久都没有用,因为你的方法上已经加了内置锁,在你一个方法中睡觉的同时,另外一个方法只能在这个锁上面等待,变成了串行执行。所以,m1m2两方法的顺序,决定了最后的结果。 --------------------编程问答-------------------- 我执行了你的代码,有时候会打印出2000的。这个主意还是多线程的问题。
1、首先这里有2个线程,1个是主线程,1个是t线程。
2、如果t线程的m1()方法被先执行,主线程的m2()方法后执行的话,就会打印出2000.
3、如果主线程的m2()方法先执行,t线程的m1()方法后执行的话,就可能打印出1000.
4、而且就算主线程的m2()方法执行完,即tt.m2()代码被执行完,cpu也可能立刻唤醒t线程去执行m1()方法,所以还是有可能先执行m1()方法,最后打印System.out.println("main to print b=" + tt.b);这句。
5、如果你一定要打印出2000的话,就在t.start()后面让主线程等待1秒,这样cpu就会立刻执行t线程,不会出现先执行主线程,后执行t线程的情况了。
--------------------编程问答-------------------- m1 sleep 5000
Why tt = new Why();
Thread t = new Thread(tt);
t.start();
Thread.sleep(1000);
tt.m2();
System.out.println("main to print b=" + tt.b);
m2 sleep 6000 //把这里改成1000试试 --------------------编程问答-------------------- 楼上大家说的很好啊。就是主线程休息后怎么调度。mi 和M2 的执行顺序。一个是主线程和一个T1
线程。
补充:Java , Java SE