黑马程序员技术交流社区
标题:
关于同步线程的问题,分享给大家
[打印本页]
作者:
sanguodouble1
时间:
2014-3-5 16:12
标题:
关于同步线程的问题,分享给大家
本帖最后由 sanguodouble1 于 2014-3-6 19:28 编辑
刚才在网上看到一道关于同步线程的笔试题,
自己整理如下
package Luntai;
//直接将此类定义为线程类
public class Test1 implements Runnable {
// 一个成员变量
int b = 100;
// 不多说,重写run()
public void run() {
m1();
}
public synchronized void m1() {
b = 1000;
// 等个5秒
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("m1方法输出" + b);
}
public void m2() {
System.out.println("m2方法输出" + b);
}
public static void main(String[] args) {
Test1 mt = new Test1();
Thread tt = new Thread(mt);
// 用tt线程调m1方法
tt.start();
// 等个半秒,确保tt拿到了同步锁
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 然后用主线程调用m2方法
mt.m2();
}
}
复制代码
问,程序的输出结果?
自己分析了下有3种可能
1.
m2方法输出1000
m1方法输出1000
2.
m2方法输出100
m1方法输出1000
3.在m1执行完前m2不能执行,所以是
m1方法输出1000
m2方法输出1000
由于同步学的比较久了,很多都忘了,坐等详见,另外自己查资料中
自我补充:如果方法m2也加上synchronized关键字,答案又是怎么样的呢?
作者:
谭荣强
时间:
2014-3-5 22:26
我看三种都有可能,但那时数学上的概率,计算机实现不了
作者:
sanguodouble1
时间:
2014-3-6 08:57
没人解答,自我解答
查了下资料+温习了一下,现整理关于同步线程的一些知识点如下:1.
synchronized锁定的不是方法,而是当前对象,包括成员变量
什么时候解开呢?就是在加锁的大括号执行完后
wait()和sleep()最大的区别:sleep()方法不会释放当前对象的同步锁,而wait()方法会释放同步锁
2.
死锁的预防:
a.逻辑上的预防
b.加大锁的粒度,也就是大家要锁的对象范围
3.
Thread.sleep()睡眠的是当前正在执行的线程
4.
在一个线程正在执行一个对象的synchronized的方法时,其他线程仍然可以执行这个对象的非synchronized方法(这个就是说,在执行同步方法时,需要得到这个对象的同步锁;但对于非同步方法,就没这个要求了)
5.
在一个对象调用notify()方法的时候,当前对象的监听线程正持有同步锁,因此,虽然其他线程被叫醒了,但仍然需要等这个线程执行完synchronized语句块后,释放锁后,其他线程才能公平争夺同步锁。
也就是说,调用wait()语句后,马上释放锁,后面的语句都不会被执行(直到被叫醒)
而在notify()语句后面,一直会执行完synchronized语句块后才会释放同步锁
--------------------------------------------------------------------------------------------------------------
那么,这题显而易见,用到了
第4个
知识点
解释一下:线程
tt.start();在调用m1方法时取得了这个对象的同步锁,并且将b的值改为1000,然后睡了5秒。
在线程tt睡觉的时候,主线程调用了m2方法,由于
m2方法并不是同步方法
,所以主线程不需要去获得对象同步锁就能执行,所以先输出m2方法里的语句
也是就是:“
m2方法输出1000”
然后tt线程睡醒了,接着再输出"m1方法输出1000",也就是原题的答案是第一种可能。
然后分析我自己的补充题:
前面一样,但是在主线程调用m2方法时,由于m2方法也变成了同步方法,所以主线程需要取得当前对象的同步锁才能执行m2方法,而此时的同步锁
被正在睡觉的m1霸占着,所以,m2方法只能等m1执行完释放同步锁后才能接着执行
也就是输出的答案是
m1方法输出1000
m2方法输出1000
作者:
sanguodouble1
时间:
2014-3-6 08:59
本帖最后由 sanguodouble1 于 2014-3-6 09:01 编辑
1楼的兄弟可能没看仔细,这个不是概率问题,不信你自己去运行,结果都是一样的
楼上是我自己的一些分析,如有不当,欢迎指正如果没什么疑问的话,我晚上结题了
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2