有如下程序1 public class TT implements Runnable {
2 int b = 100;
3
4 public synchronized void m1() throws Exception{
5 b = 1000;
7 System.out.println("b = " + b);
8 }
9
10 public synchronized void m2() throws Exception {
11 //Thread.sleep(2500);
12 b = 2000;
13 }
14
15 public void run() {
16 try {
17 m1();
18 } catch(Exception e) {
19 e.printStackTrace();
20 }
21 }
22
23 public static void main(String[] args) throws Exception
24{
25 TT tt = new TT();
26 Thread t = new Thread(tt);
27 t.start();
28 tt.m2();//先拿到锁?
30 System.out.println(tt.b);
31 }
}
运行结果
1.不解开注释,2000
b=1000
3. 解开第11行 1000
b=1000
我的问题是:
1.解开11行后,为什么就变成先输出2000?
2. 解开11行后,为什么说m2先拿到锁?
3.解开11行后,如果是m2先拿到锁,那么m2结束时是先运行主线程(System.out.println(tt.b);)还是m1拿到锁运行?
我在马士兵视频里看的这个,觉得讲的不是很明白,希望有人能把线程给我讲个明明白白!!这个东西我脑子里现在乱成一团!!
2 int b = 100;
3
4 public synchronized void m1() throws Exception{
5 b = 1000;
7 System.out.println("b = " + b);
8 }
9
10 public synchronized void m2() throws Exception {
11 //Thread.sleep(2500);
12 b = 2000;
13 }
14
15 public void run() {
16 try {
17 m1();
18 } catch(Exception e) {
19 e.printStackTrace();
20 }
21 }
22
23 public static void main(String[] args) throws Exception
24{
25 TT tt = new TT();
26 Thread t = new Thread(tt);
27 t.start();
28 tt.m2();//先拿到锁?
30 System.out.println(tt.b);
31 }
}
运行结果
1.不解开注释,2000
b=1000
3. 解开第11行 1000
b=1000
我的问题是:
1.解开11行后,为什么就变成先输出2000?
2. 解开11行后,为什么说m2先拿到锁?
3.解开11行后,如果是m2先拿到锁,那么m2结束时是先运行主线程(System.out.println(tt.b);)还是m1拿到锁运行?
我在马士兵视频里看的这个,觉得讲的不是很明白,希望有人能把线程给我讲个明明白白!!这个东西我脑子里现在乱成一团!!
Thread.sleep(2500); 这句被注释掉,输出结果是
2000
b = 1000
----------------------------------
Thread.sleep(2500); 这句没有被注释掉,输出结果是
1000
b = 1000
---------------------------------像 public synchronized void m2() 这样对方法加同步,是针对此对象的同步,
即如果一个线程进入了m2()方法,则被定义为public synchronized void m1()的方法,就要等待
m2结束了,锁释放了才能进入执行。1.Thread.sleep(2500); 被注释掉的时候,
在main方法里,虽然是先调用的t.start();
但是run方法并不会马上执行,需要一定时间来启动执行。
而此时 执行了:
tt.m2();
System.out.println(tt.b);
b马上被赋值为2000,然后释放了锁,打印输出2000,
之后才走run方法,又调用了m1方法,输出了b=10002.不管11行是否被注释掉,m2都是先拿到锁。只是当11行没有被注释掉的时候,m2拿到了锁,然后
调用了Thread.sleep(2500); 并没有马上给b赋值为2000
而sleep方法不会释放对象锁,所以m2在sleep的过程中依然持有锁。而利用这个时间,线程已经启动,已经执行了run方法,但调用m1的时候,发现没有锁,
就阻塞了。所以你执行的时候会等一会,发现控制台什么都没有输出。所以当m2退出,释放了锁,m1立即执行了,所以输出的就是
1000
b=1000
3.m2结束时是先运行主线程(System.out.println(tt.b);)还是m1拿到锁运行?这个不一定。
但是
System.out.println(tt.b); 和 m1之间没有同步约束。
run方法的“迟钝时间”能让
tt.m2();
System.out.println(tt.b); 都运行完毕?但当m2中一睡眠,run才调用了m1,开始等待锁?可不可以认为m1只要被调用了,即使阻塞,只要另一个线程释放了锁,m1保证第一个运行?