分享

java两种经典死锁例子,Lock发生死锁案列

 WindySky 2018-03-06

  1. 第一种synchronized方式死锁:  
  1. 线程thread1先获取锁locka,然后在同步块里嵌套竞争锁lockb。而线程thread2先获取锁lockb,然后在同步块里嵌套竞争锁locka  
  1. (此时已经被线程thread1拥有,而thread1在等待lockb,而lockb被thread2拥有,thread2在等待locka……无线循环)。  
  1. package com.app.test;  
  2.   
  3. import org.apache.poi.util.SystemOutLogger;  
  4.   
  5. /** 
  6.  * Created by lirong5 on 2016/5/24. 
  7.  */  
  8. public class SyncDeadLock{  
  9.     private static Object locka = new Object();  
  10.     private static Object lockb = new Object();  
  11.   
  12.     public static void main(String[] args){  
  13.         new SyncDeadLock().deadLock();  
  14.     }  
  15.   
  16.     private void deadLock(){  
  17.         Thread thread1 = new Thread(new Runnable() {  
  18.             @Override  
  19.             public void run() {  
  20.                 synchronized (locka){  
  21.                     try{  
  22.                         System.out.println(Thread.currentThread().getName()+" get locka ing!");  
  23.                         Thread.sleep(500);  
  24.                         System.out.println(Thread.currentThread().getName()+" after sleep 500ms!");  
  25.                     }catch(Exception e){  
  26.                         e.printStackTrace();  
  27.                     }  
  28.                     System.out.println(Thread.currentThread().getName()+" need lockb!Just waiting!");  
  29.                     synchronized (lockb){  
  30.                         System.out.println(Thread.currentThread().getName()+" get lockb ing!");  
  31.                     }  
  32.                 }  
  33.             }  
  34.         },"thread1");  
  35.   
  36.         Thread thread2 = new Thread(new Runnable() {  
  37.             @Override  
  38.             public void run() {  
  39.                 synchronized (lockb){  
  40.                     try{  
  41.                         System.out.println(Thread.currentThread().getName()+" get lockb ing!");  
  42.                         Thread.sleep(500);  
  43.                         System.out.println(Thread.currentThread().getName()+" after sleep 500ms!");  
  44.                     }catch(Exception e){  
  45.                         e.printStackTrace();  
  46.                     }  
  47.                     System.out.println(Thread.currentThread().getName()+" need locka! Just waiting!");  
  48.                     synchronized (locka){  
  49.                         System.out.println(Thread.currentThread().getName()+" get locka ing!");  
  50.                     }  
  51.                 }  
  52.             }  
  53.         },"thread2");  
  54.   
  55.         thread1.start();  
  56.         thread2.start();  
  57.     }  
  58. }  


执行main方法之后控制台打印内容如下:

thread1 get locka ing!
thread2 get lockb ing!
thread1 after sleep 500ms!
thread1 need lockb!Just waiting!
thread2 after sleep 500ms!
thread2 need locka! Just waiting!


thread1 need lockb!Just waiting!表明thread1线程进入死锁等待lockb释放。

thread2 need locka! Just waiting!  表明thread2线程进入死锁等待locka释放。 


第二种concurrent包Lock错误使用,导致死锁:

lock.unlock();释放锁使用地方不规范,导致死锁不能正常释放!

  1. package com.app.test;  
  2.   
  3. import java.util.concurrent.locks.Lock;  
  4. import java.util.concurrent.locks.ReentrantLock;  
  5.   
  6. /** 
  7.  * Created by lirong5 on 2016/5/24. 
  8.  */  
  9. public class LockDeadDemo {  
  10.   
  11.     public static void main(String[] args){  
  12.         final DeadLockBean deadLockBean = new DeadLockBean();  
  13.         Thread threadA = new Thread(new Runnable() {  
  14.             @Override  
  15.             public void run() {  
  16.                 try {  
  17.                     Thread.sleep(300);  
  18.                 } catch (InterruptedException e) {  
  19.                     e.printStackTrace();  
  20.                 }  
  21.                 try {  
  22.                     deadLockBean.productDeadLock();  
  23.                 } catch (Throwable throwable) {  
  24.                     throwable.printStackTrace();  
  25.                 }  
  26.             }  
  27.         },"threadA");  
  28.         Thread threadB = new Thread(new Runnable() {  
  29.             @Override  
  30.             public void run() {  
  31.                 try {  
  32.                     Thread.sleep(310);  
  33.                 } catch (InterruptedException e) {  
  34.                     e.printStackTrace();  
  35.                 }  
  36.                 try {  
  37.                     deadLockBean.productDeadLock();  
  38.                 } catch (Throwable throwable) {  
  39.                     throwable.printStackTrace();  
  40.                 }  
  41.             }  
  42.         },"threadB");  
  43.         threadA.start();  
  44.         threadB.start();  
  45.         try {  
  46.             System.out.println("main线程即将被join");  
  47.             threadA.join();  
  48.             threadB.join();  
  49.             System.out.println("main线程从join中恢复");  
  50.         } catch (InterruptedException e) {  
  51.             e.printStackTrace();  
  52.         }  
  53.     }  
  54.   
  55.     public static class DeadLockBean{  
  56.         private Lock lock = new ReentrantLock();  
  57.         public void productDeadLock() throws Throwable {  
  58.             System.out.println(Thread.currentThread().getName() + "   进入了方法!");  
  59.             lock.lock();  
  60.             try{  
  61.                 System.out.println(Thread.currentThread().getName() + "   已经执行了!");  
  62.                 throw new Throwable("人为抛出异常Throwable");//关键代码行1,  
  63.                 //throw new Exception("人为抛出异常Exception");//关键代码行2,不会死锁,会在catch(Exception e中被捕获),嵌套lock.unlock()并释放  
  64.             }catch(Exception e){  
  65.                 System.out.println(Thread.currentThread().getName()+"   发生异常catch!");  
  66.                 //lock.unlock();//关键代码行3,不建议在这里释放,假如发生【关键代码行1】会产生死锁  
  67.             }finally{  
  68.                 System.out.println(Thread.currentThread().getName()+"   发生异常finally!");  
  69.                 lock.unlock();//关键代码行4,无论发生何种异常,均会释放锁。  
  70.             }  
  71.             //lock.unlock();//关键代码行5,假如发生不能捕获异常,将跳出方法体,不执行此处  
  72.             System.out.println(Thread.currentThread().getName() + "   tryCatch外释放锁!");  
  73.         }  
  74.     }  
  75. }  


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多