[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
相關文章
- 用個通俗的例子講一講死鎖
- 使用jstack檢測Java應用的死鎖(deadlock)狀態JSJava
- 關於 SAP HANA 資料庫的死鎖問題(deadlock)資料庫
- ABAP面試題系列:寫一組會出現死鎖(Deadlock)的ABAP程式面試題
- MySQL:一個死鎖分析 (未分析出來的死鎖)MySql
- mysql死鎖deadlock相關幾個系統變數innodb_lock_wait_timeoutMySql變數AI
- Java 中的死鎖Java
- ORA-00060: Deadlock detected 模擬死鎖產生與解決方案
- MySQL:Innodb 一個死鎖案例MySql
- 例項詳解 Java 死鎖與破解死鎖Java
- Java中常見死鎖與活鎖的例項Java
- 剖析6個MySQL死鎖案例的原因以及死鎖預防策略MySql
- java如何避免程式死鎖Java
- [Java併發]避免死鎖Java
- java中死鎖是什麼Java
- 使用javap分析Java位元組碼的一個例子Java
- 涉及到一個deadlock event monitor的問題
- 作業系統(5) 死鎖的概念 死鎖產生的必要條件 死鎖的處理策略 預防死鎖 避免死鎖 死鎖的檢測和解除 銀行家演算法作業系統演算法
- Oracle死鎖一例(ORA-00060),鎖表導致的業務死鎖問題Oracle
- MySQL:死鎖一例MySql
- Java多執行緒(五):死鎖Java執行緒
- java多執行緒(5)死鎖Java執行緒
- 面試官:請用SQL模擬一個死鎖面試SQL
- 死鎖
- 鎖的使用與死鎖的避免
- 面試:什麼是死鎖,如何避免或解決死鎖;MySQL中的死鎖現象,MySQL死鎖如何解決面試MySql
- MySQL死鎖案例一(回滾導致死鎖)MySql
- expdp一個例子
- 一個具體的例子學習Java volatile關鍵字Java
- SQL Server 的死鎖SQLServer
- SQLServer的死鎖分析(1):頁鎖SQLServer
- 從一個死鎖問題分析最佳化器特性
- 死磕java concurrent包系列(一)從樂觀鎖、悲觀鎖到AtomicInteger的CAS演算法Java演算法
- 什麼是死鎖?如何解決死鎖?
- 記一次神奇的Mysql死鎖排查MySql
- java多執行緒中的死鎖、活鎖、飢餓、無鎖都是什麼鬼?Java執行緒
- 一個複雜的json例子JSON
- 一個簡單的「IOC」例子
- 面試官:什麼是死鎖?怎麼排查死鎖?怎麼避免死鎖?面試