大家都知道多線程併發的時候,我們一般會用到鎖。但是鎖用不好,就會導致死鎖。那麼,死鎖是如何產生的呢?
一般造成死鎖必須同時滿足如下4個條件:
- 互斥條件:線程使用的資源必須至少有一個是不能共享的。
- 請求與保持條件:至少有一個線程必須持有一個資源並且正在等待獲取一個當前被其他線程持有的資源。
- 非剝奪條件:分配的資源不能從相應的線程中被強制剝奪。
- 循環等待條件:第一個線程等待其他線程,後者又在等待第一個線程。
接下來我們來看一段手寫的死鎖代碼
package com.sync;
/**
* 手寫一個死鎖
*
* @author 小輝GE/小輝哥
* <p>
* 2019年8月10日 下午18:30:00
*/
public class DeadLock {
public static void main(String[] args) {
Object obj1 = new Object();
Object obj2 = new Object();
Runner r1 = new Runner(obj1, obj2, 5000);
Runner r2 = new Runner(obj2, obj1, 5000);
new Thread(r1, "r1").start();
new Thread(r2, "r2").start();
}
}
class Runner implements Runnable {
private Object o1;
private Object o2;
private int sleepTime;
public Runner(Object o1, Object o2, int sleepTime) {
this.o1 = o1;
this.o2 = o2;
this.sleepTime = sleepTime;
}
public void run() {
System.out.println("當前線程" + Thread.currentThread().getName() + "獲得鎖");
synchronized (o1) {
try {
// 這裏主要是放大效果
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (o2) {
System.out.println();
}
}
}
}
測試輸出結果如下:
結果分析:
其實我們不難看出,線r1啓動時候先獲得obj1對象鎖且需要獲得obj2對象鎖,線程r2啓動時先獲得obj2對象鎖且需要獲取obj1對象鎖,這就同時滿足了死鎖的條件,也就出現了死鎖。
以上代碼僅供參考,如有不當之處,歡迎指出!!!
更多幹貨,歡迎大家關注和聯繫我。期待和大家一起更好的交流、探討技術!!!