A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 李会成 中级黑马   /  2013-2-2 14:15  /  2091 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 李会成 于 2013-2-4 15:17 编辑

为什么在方法声明的时候用到了关键字synchronized  后再在方法体中用synchronized就会发生死锁的情况呢!
   如果我们不用同一个锁对象就不是不会发生死锁的情况了吗?求解释,还有死锁还有那些情况导致呢?
      平时写线程的时候要都注意些那些方面呢?

3 个回复

倒序浏览
  1. class A  
  2. {  
  3.     public void get(){  
  4.         System.out.println("A说:我开始启动了,B,给我你的资源");  
  5.     }  
  6.     public void say(){  
  7.         System.out.println("A获得资源");  
  8.     }  
  9. }  
  10. class B  
  11. {  
  12.     public void get(){  
  13.         System.out.println("B说:我开始启动了,A,给我你的资源");  
  14.     }  
  15.     public void say(){  
  16.         System.out.println("B获得资源");  
  17.     }  
  18. }  
  19. class MyThread implements Runnable  
  20. {  
  21.     public static A a = new A();  
  22.     public static B b = new B();  
  23.     public boolean flag = false;  
  24.     public void run(){  
  25.         if(flag){  
  26.             synchronized(a){  
  27.                 a.get();  
  28.                 try{  
  29.                     Thread.sleep(500);  
  30.                 }catch(InterruptedException e){}  
  31.                   
  32.                 synchronized(b){     //此同步代码块在另一同步代码块里   
  33.                 a.say();  
  34.                 }  
  35.               
  36.             }  
  37.               
  38.          
  39.         }else{  
  40.             synchronized(b){  
  41.                 b.get();  
  42.                 try{  
  43.                     Thread.sleep(500);  
  44.                 }catch(InterruptedException e){}  
  45.               
  46.             synchronized(a){     //此同步代码块在另一同步代码块里   
  47.                   
  48.                 b.say();  
  49.             }  
  50.             }  
  51.               
  52.         }     
  53.     }  
  54. }  
  55. public class Demo24  
  56. {  
  57.     public static void main(String args[]){  
  58.         MyThread mt1 = new MyThread();  
  59.         MyThread mt2 = new MyThread();  
  60.         mt1.flag=true;  
  61.         mt2.flag=false;  
  62.         Thread th1 = new Thread(mt1);  
  63.         Thread th2 = new Thread(mt2);  
  64.         th1.start();  
  65.         th2.start();  
  66.     }  
  67. }  
复制代码
以上代码由于synchronized的同步造成了死锁,死锁是两个或多个线程同时等待对方的完成,而程序无法继续执行。
在java中,每一个对象都有一个内部锁,如果以方法或代码块用synchronized进行声明,那么对象的锁将保护整个方法或代码块,要调用这个方法或者执行这个代码块,必须获得这个对象的锁。而且,任何时候都只能有一个线程对象执行被保护的代码

在以上代码中,在线程th1启动后,他就获得了a的锁,同时当其休眠完毕,求会申请获得b的锁,而此时,他的a锁没有放弃。在线程th2启动后,他就获得了b的锁,同时当其休眠完毕,求会申请获得a的锁,而此时,他的b锁没有放弃.两方都握有自己的锁不放弃,而同时申请另一方的锁,所以,此时就造成了死锁。同步的就是线程和对象,将线程和对象进行绑定,获取对象的锁。

注意:通过以上代码可以发现,死锁的必要条件是不放弃已有的锁,而同时申请新锁。所以,要想实现死锁,就会有synchronized的嵌套。这样才能同时操作两个以上的锁,从而造成死锁。
回复 使用道具 举报
不要相互嵌套的同时使用两把锁,这样很容易导致拿着一把等对方的一把,对方也是在这样。。。
这个貌似是故意要程序死锁的。。。
回复 使用道具 举报
请勿复制他人帖子,技术分不是入学的门槛而是为了帮助大家学习而存在的。

请勿再次发此类帖子了!

此贴就关闭了。此后如有再次发现直接封禁处理,请看到此贴的会员也加以注意。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马