[Java]一個DeadLock(死鎖)的例子
今天在InteliJ裡跑了一下,模擬了一個死鎖。synchronized
關鍵字修飾的方法可能會導致死鎖。(Synchronized只能修飾方法,就像volatile只能修飾變數)。
先簡單介紹一下,下面這個死鎖產生的原因,是A執行緒需要依次獲取lock1和lock2才能分別列印一句話,B執行緒需要依次獲取lock2和lock1才能分別列印一句話,那兩個執行緒非同步執行的時候,有兩種情況:
情形1:
A迅速地依次持有lock1,持有lock2,釋放lock2,釋放lock1,順利地列印了兩句話。
然後B持有lock2,持有lock1,釋放lock1,釋放lock2,也順利地列印了兩句話。
情形2:
A持有了lock1,列印了第一句話(沒有釋放lock1),此時B持有了lock2,列印了第一句話;接著A想持有lock2了,就等著B釋放lock2,但是lock2是釋放不掉的,因為lock2要想釋放,就必須先獲取lock1並執行任務。
注意,兩把鎖一定要巢狀呼叫。
看程式碼比較容易理解:
public class TestDeadLock {
public void run() {
MyThread mt = new MyThread();
new Thread(mt, "張三").start();
new Thread(mt, "李四").start();
}
class MyThread implements Runnable {
//lock要寫成final的,否則如果lock指向變了,鎖就失效了
private final Object mLock1 = new Object();
private final Object mLock2 = new Object();
//boolean用來確保兩個執行緒獲得不同的鎖。
private boolean flag = true;
@Override
public void run() {
if (flag) {
flag = false;
//注意,兩把鎖一要巢狀呼叫
synchronized (mLock1) {
System.out.println(Thread.currentThread().getName() + " have mLock1");
// try {
// Thread.sleep(100);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
synchronized (mLock2) {
System.out.println(Thread.currentThread().getName() + " have mLock2");
}
}
} else {
flag = true;
synchronized (mLock2) {
System.out.println(Thread.currentThread().getName() + " have mLock2");
// try {
// Thread.sleep(100);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
synchronized (mLock1) {
System.out.println(Thread.currentThread().getName() + " have mLock1");
}
}
}
}
}
public static void main(String[] args) {
new TestDeadLock().run();
}
}
我把sleep的部分去掉了,這樣由於執行緒搶佔CPU資源,每次執行的結果會不同(上面提到的兩種情形)。
下面的截圖對應第一種情形:
下面的截圖對應第二種情形,一直卡在這兒了,死鎖出現了:
那如果放開sleep的註釋,就會必現第二種情形了。
Ref:
http://blog.csdn.net/u011345136/article/details/45770835
http://blog.csdn.net/qinjienj/article/details/7578582
相關文章
- 分散式死鎖的一個例子分散式
- 死鎖_DeadLock_示例
- oracle deadlock死鎖trace file分析之一Oracle
- 【DEADLOCK】Oracle“死鎖”模擬Oracle
- oracle lock轉換及oracle deadlock死鎖系列一Oracle
- oracle deadlock死鎖trace file分析之一增補Oracle
- 使用jstack檢測Java應用的死鎖(deadlock)狀態JSJava
- RDSSQLServer死鎖(Deadlock)系列之三自動部署Profiler捕獲死鎖SQLServer
- Java 死鎖(DeadLock)例項分析和預防[base jdk8]JavaJDK
- MySQL:一個死鎖分析 (未分析出來的死鎖)MySql
- Java鎖——死鎖Java
- ABAP面試題系列:寫一組會出現死鎖(Deadlock)的ABAP程式面試題
- 關於 SAP HANA 資料庫的死鎖問題(deadlock)資料庫
- Java 中的死鎖Java
- MySQL:Innodb 一個死鎖案例MySql
- 一個MySQL死鎖問題的反思MySql
- 【死鎖】ORA-00060: deadlock detected while waiting for resourceWhileAI
- 測試庫死鎖診斷DEADLOCK DETECTED ( ORA-00060 )
- 使用oracle 10704 event分析獲取鎖lock及死鎖deadlock系列九Oracle
- 例項詳解 Java 死鎖與破解死鎖Java
- 一個MySQL死鎖問題的復現MySql
- 一個ORACLE死鎖問題的追蹤Oracle
- 基於10.2.0.1 rac deadlock死鎖 trace file分析_增補二
- mysql死鎖deadlock相關幾個系統變數innodb_lock_wait_timeoutMySql變數AI
- 這樣分析一個死鎖問題
- 一個最不可思議的 MySQL 死鎖分析MySql
- 剖析6個MySQL死鎖案例的原因以及死鎖預防策略MySql
- Java中常見死鎖與活鎖的例項Java
- java如何避免程式死鎖Java
- oracle deadlock 之(一)--鎖機制介紹Oracle
- deadlock引起資料庫掛死資料庫
- MYSQL中一個特殊的MDL LOCK死鎖案列MySql
- SQ死鎖及死鎖的解決
- ORA-00060: Deadlock detected 模擬死鎖產生與解決方案
- select for update語句造成ORA-00060 deadlock死鎖問題分析
- java中死鎖是什麼Java
- 面試官:請用SQL模擬一個死鎖面試SQL
- 作業系統(5) 死鎖的概念 死鎖產生的必要條件 死鎖的處理策略 預防死鎖 避免死鎖 死鎖的檢測和解除 銀行家演算法作業系統演算法