您的位置:首页 > 移动开发

StringBuffer append 死锁

2016-06-04 20:16 387 查看
public class Ss1 {

/**
* @param args
*/
public static void main(String args[]){
Integer i = new Integer(50);
StringBuffer sb = new StringBuffer("1234");
MyThread mt1 = new MyThread(sb);
mt1.start();
synchronized(sb){
//mt1.change();
try {
mt1.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void changeNumber(Integer i){
i = 100;
}

}
class MyThread extends Thread{
StringBuffer sb;
public MyThread(StringBuffer sb) {
// TODO Auto-generated constructor stub
this.sb = sb;
}
public void run(){
sb.append("asdf");
}
public void change(){
synchronized(sb){
sb.append("adsf");
}
}
}
请问在main方法中synchronized锁住的是哪一个对象,sb还是mt1
为什么join()方法会造成死锁,而change方法不会造成死锁
在change()方法中synchronized锁住的是MyThread还是sb

answer:

synchronized锁住的不是对象,是后面{}里的代码块,就是后面的代码块对不同的线程是互斥的
每个对象(注意是对象,不是类)都有一个监视器(monitor),只能有一个线程获得,synchronized(obj)就是获得obj的监视器,第一个线程获得了,其它线程再执行synchronized(obj)想获得obj的监视器就只能等待第一个线程把后面的代码块执行后释放obj的监视器
mt1.join的意思是要当前线程等待mt1执行完成后才能继续执行
StringBuffer.append的声明: public synchronized StringBuffer append(Object obj) ,它也是个同步方法,也需要获得当前对象的监视器
synchronized(sb) { //当前线程获得sb的监视器
mt1.join(); //当前线程等待mt1执行完
}
而mt1的run()方法里调用 sb.append,它需要获得sb的监视器,而它的监视器被主线程占用,只好等待主线程释放sb的监视器,所以主线程与mt1都在互相等待,只好死锁了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: