package com.test;
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;
}
=======================================
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();
}
}
=======================================
小弟认为结果应该是2000,理由:在m1执行后此时b值为1000且休眠5秒,但是m2将b值修改为2000且休眠2.5秒,等到m1的5秒结束后显示b值,此时b值为2000。
但是,系统出来的结果是1000,小弟不理解,请求指点。谢谢!
流程分析:首先主线程执行创建一个套套(tt)对象(注意:此对象只有一把锁),然后再创建一个t线程并开启。
t线程和主线程争抢控制权,假设t线程获得控制权,进入run方法执行m1(注意:m1使用套套的锁),m1使t线程睡眠
5秒(注意:但并未释放套套的锁),在这段时间主线程又获得了控制权,主线程调用m2(注意:m2也是使用synchronized修饰)
方法,但是套套的锁还在m1中使用,主线程就尝试去获取这把锁,所以只有m1执行完释放锁,主线程才能获得这把锁,
才能执行m2方法。去掉m2的synchronized即可获得你想要的结果。手打不易不喜勿喷。
1.b = 100
2.t.start()->1000 sysout
3.tt.m2()->2000 你没输出
尴尬-------
你这个人啊,问题真多。只可言传不可意会,对象只有一个,锁也只有一个。
package com.test;
public class TT implements Runnable {
int b = 100;
public synchronized void m1() throws Exception {
b = 1000;
System.out.println("m1执行完毕,b = " + b);
}
public synchronized void m2() throws Exception {
b = 2000;
System.out.println("m2执行完毕,最终b值" + 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();
tt.m2();
tt.m2();
}
}
得到的结果如下:
m2执行完毕,最终b值2000
m2执行完毕,最终b值2000
m2执行完毕,最终b值2000
m1执行完毕,b = 1000
(这个结果我运行了很多次都一样)
所以我认为:不应该是在上一个synchronized修饰的方法运行完毕之后再运行下一个synchronized修复的方法。
t.start() 告诉系统它现在准备好了随时可以运行,但在t.start()下还有3个m2要执行,执行完毕3个m2后系统认为有资源可以运行t.start()了,此时t.start()才正式开始运行。
不知道这样理解对不。
真正的问题是其实先执行的是m2而并不是m1,学习多线程的时候一定要注意,并不是写在前面的代码一定先执行,按我这样加几个注释就很清楚了
public class Qquestions_380568 {
static class TT implements Runnable {
int b = 100;
public synchronized void m1() throws Exception {
System.out.println("---------m1执行,此时m1方法获取锁-----------");
b = 1000;
Thread.sleep(5000);
System.out.println("---------m1执行,此时m1方法释放锁-----------");
System.out.println("b = " + b);
}
public synchronized void m2() throws Exception {
System.out.println("---------m2执行,此时m2方法获取锁-----------");
Thread.sleep(2500);
b = 2000;
System.out.println("---------m2执行完成,此时m2方法释放锁-----------");
}
@Override
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();
}
}