黑马程序员技术交流社区
标题:
一个关于线程同步的问题
[打印本页]
作者:
张源锋
时间:
2013-4-1 23:11
标题:
一个关于线程同步的问题
本帖最后由 无奈№追夜 于 2013-4-2 17:34 编辑
package Test1;
public class Test extends Thread {
int b = 100;
public synchronized void m1() throws Exception{
//Thread.sleep(2000);
b = 1000;
Thread.sleep(5000);
System.out.println("b = " + b);
}
public synchronized void m2() throws Exception {
Thread.sleep(2500);
b = 2000;
}
public void run() {
try {
m1();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
Test tt = new Test();
Thread t = new Thread(tt);
t.start();
tt.m2();
System.out.println(tt.b);
}
}
复制代码
结果:
1000
b = 1000
m1()方法最打印的为什么不是200???main方法打印的为什么不是200???求解
还用
public void m2() throws Exception {
Thread.sleep(2500);
b = 2000;
}
复制代码
若改成如上这是结果是都是2000,为什么啊,头大
作者:
王瑞
时间:
2013-4-2 08:31
问题解决了吗,哥们?我的解释如下,表达有点混乱,哪里没看懂继续留言
class Test extends Thread {
int b = 100;
public synchronized void m1() throws Exception{
//Thread.sleep(2000);
b = 1000;
Thread.sleep(5000);
System.out.println("b = " + b);
}
public synchronized void m2() throws Exception {//有锁,运行时只能运行一个线程
Thread.sleep(2500);
b = 2000;
}
public void run() {
try {
m1();//这个地方只执行m1
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
Test tt = new Test();
Thread t = new Thread(tt);
t.start();//开启t的线程,同时执行run函数,这时候只执行m1,m1会沉睡5秒,所以会先向下执行
tt.m2();//这里,虽然执行m2,但是沉睡了2.5秒,所以main线程继续向下执行。
System.out.println(tt.b);//这时候,首先输出b,因为在m1沉睡钱被赋值,所以此时一定为1000,main线程结束,这个时候先等待唤醒t线程,不会因为m2沉睡2.5秒,m2先醒来。因为t唤醒后执行b的输出语句,就是10000
}
}
/*
public void m2() throws Exception
Thread.sleep(2500);
b = 2000;
如果用上面的语句替换m2,那么m2和m1没有同步,这样的话,m2沉睡2.5秒就会醒来,m1和这个线程没有同步,m1沉睡5秒,这个时候b会被赋值,最终值b为2000,所以输出的b都是2000
*/
复制代码
作者:
赵海洋
时间:
2013-4-2 10:49
开启t线程,执行代码,run方法,m1中,b被赋值为1000,然后沉睡5000毫秒,不继续执行,往下走。到m2,直接sleep2500毫秒,不执行b=2000,继续往下走。此时到达main函数的输出语句,所以main函数输出了b值为1000.等待进程被唤醒,此时m1和m2是同步的,所以只好等待t线程被唤醒,执行m1,输出了b=1000.然后m2才会执行,b被赋值为2000.
代码修改去掉同步后,b会在m2中被赋值,然后在继续执行,就是这有区别,所以打印结果不同。
作者:
刘渝灵
时间:
2013-4-2 12:53
我的理解:本例一共就2个线程:线程t和主线程。线程t.start后,究竟是t先运行还是主线程先运行,取决于cpu。因此可能有不同结果。
运行多遍,主线程先运行完这种情况也不奇怪。想要看到t先运行,可以在main方法中加一个sleep语句,让主线程冻结。
public static void main(String[] args) throws Exception {
Test tt = new Test();
Thread t = new Thread(tt);
t.start();
try
{
Thread.sleep(10);
}
catch (Exception e)
{
}
tt.m2();
System.out.println(tt.b);
}
复制代码
这时,结果与之前就会不同。
作者:
随便
时间:
2013-4-2 15:01
首先就是本例main中一共两个线程,一个主线程一个子线程。子线程start()运行tt.run(){m1()}沉睡5秒。
此时主线程同时可以执行tt.m2();因为m1(),m2()互斥,所以m2()不能执行,主线程继续向下执行到System.out.println(tt.b);
tt.b已经被m1()修改成了1000所以先打印 1000
然后tt.m1()沉睡结束打印 b = 1000,
然后执行m2()中的吧= 2000;
如果main()最后加上Thread.sleep(5000+2500);System.out.println(tt.b);在打印就会使m2中给定的2000了。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2