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都在互相等待,只好死锁了
StringBuffer append 死锁
最新推荐文章于 2025-03-12 15:44:30 发布