java-synchronized 嵌套使用

当synchronized使用过多时,可能会造成死锁,那么死锁到底是怎么一回事呢。先看下面的代码,实现死锁: 
Java代码   收藏代码
  1. //死锁的实现  
  2. class A  
  3. {  
  4.     public void get(){  
  5.         System.out.println("A说:我开始启动了,B,给我你的资源");  
  6.     }  
  7.     public void say(){  
  8.         System.out.println("A获得资源");  
  9.     }  
  10. }  
  11. class B  
  12. {  
  13.     public void get(){  
  14.         System.out.println("B说:我开始启动了,A,给我你的资源");  
  15.     }  
  16.     public void say(){  
  17.         System.out.println("B获得资源");  
  18.     }  
  19. }  
  20. class MyThread implements Runnable  
  21. {  
  22.     public static A a = new A();  
  23.     public static B b = new B();  
  24.     public boolean flag = false;  
  25.     public void run(){  
  26.         if(flag){  
  27.             synchronized(a){  
  28.                 a.get();  
  29.                 try{  
  30.                     Thread.sleep(500);  
  31.                 }catch(InterruptedException e){}  
  32.                   
  33.                 synchronized(b){     //此同步代码块在另一同步代码块里  
  34.                 a.say();  
  35.                 }  
  36.               
  37.             }  
  38.               
  39.           
  40.         }else{  
  41.             synchronized(b){  
  42.                 b.get();  
  43.                 try{  
  44.                     Thread.sleep(500);  
  45.                 }catch(InterruptedException e){}  
  46.               
  47.             synchronized(a){     //此同步代码块在另一同步代码块里  
  48.                   
  49.                 b.say();  
  50.             }  
  51.             }  
  52.               
  53.         }     
  54.     }  
  55. }  
  56. public class Demo24  
  57. {  
  58.     public static void main(String args[]){  
  59.         MyThread mt1 = new MyThread();  
  60.         MyThread mt2 = new MyThread();  
  61.         mt1.flag=true;  
  62.         mt2.flag=false;  
  63.         Thread th1 = new Thread(mt1);  
  64.         Thread th2 = new Thread(mt2);  
  65.         th1.start();  
  66.         th2.start();  
  67.     }  
  68. }  

以上代码由于 synchronized 的同步造成了死锁,死锁是两个或多个线程同时等待对方的完成,而程序无法继续执行。在解释代码前,首先要明白synchronized到底是怎么一回事。synchronized 定义同步,那么同步的什么,什么和什么同步了? 

首先,我们得知道,什么是锁。在java中,每一个对象都有一个内部锁,如果以方法或代码块用 synchronized 进行声明,那么对象的锁将保护整个方法或代码块,要调用这个方法或者执行这个代码块,必须获得这个对象的锁。而且,任何时候都只能有一个线程对象执行被保护的代码 

在以上代码中,在线程th1启动后,他就获得了a的锁,同时当其休眠完毕,求会申请获得b的锁,而此时,他的a锁没有放弃。在线程th2启动后,他就获得了b的锁,同时当其休眠完毕,求会申请获得a的锁,而此时,他的b锁没有放弃。 

两方都握有自己的锁不放弃,而同时申请另一方的锁,所以,此时就造成了死锁。 

同步,同步的就是线程和对象,将线程和对象进行绑定,获取对象的锁。 

注意:通过以上代码可以发现,死锁的必要条件是不放弃已有的锁,而同时申请新锁。所以,要想实现死锁,就会有synchronized的嵌套。 

这样才能同时操作两个以上的锁,从而造成死锁。


参考资料:

http://technique-digest.iteye.com/blog/1122277


  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值