多線程死鎖問題
前天俺們談到了加鎖,但是在使用加鎖的同時又會帶來一個問題,就是死鎖。
什么叫死鎖?
所謂死鎖: 是指兩個或兩個以上的進程在執行過程中,因爭奪資源而造成的一種互相等待的現象,若無外力作用,它們都將無法推進下去。
那么為什么會產生死鎖呢?
1.因為系統資源不足。
2.進程運行推進的順序不合適。
3.資源分配不當。
學過操作系統的朋友都知道:產生死鎖的條件有四個:
1.互斥條件:所謂互斥就是進程在某一時間內獨占資源。
2.請求與保持條件:一個進程因請求資源而阻塞時,對已獲得的資源保持不放。
3.不剝奪條件:進程已獲得資源,在末使用完之前,不能強行剝奪。
4.循環等待條件:若干進程之間形成一種頭尾相接的循環等待資源關系。
例如:
死鎖是因為多線程訪問共享資源,由於訪問的順序不當所造成的,通常是一個線程鎖定了一個資源A,而又想去鎖定資源B;在另一個線程中,鎖定了資源B,而又想去鎖定資源A以完成自身的操作,兩個線程都想得到對方的資源,而不願釋放自己的資源,造成兩個線程都在等待,而無法執行的情況。
分析死鎖產生的原因不難看出是由訪問共享資源順序不當所造成的,下面寫一個造成線程死鎖的例子,希望能對大家理解多線程死鎖問題有進一步的理解!如果有人需要編寫多線程的系統,當操作共享資源時一定要特別的小心,以防出現死鎖的情況!
package com.ljq.test;
public class RunnableTest implements Runnable {
private int flag = 1;
private Object obj1 = new Object(), obj2 = new Object();
public void run() {
System.out.println("flag=" + flag);
if (flag == 1) {
synchronized (obj1) {
System.out.println("我已經鎖定obj1,休息0.5秒后鎖定obj2去!");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (obj2) {
System.out.println("1");
}
}
}
if (flag == 0) {
synchronized (obj2) {
System.out.println("我已經鎖定obj2,休息0.5秒后鎖定obj1去!");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (obj1) {
System.out.println("0");
}
}
}
}
public static void main(String[] args) {
RunnableTest run01 = new RunnableTest();
RunnableTest run02 = new RunnableTest();
run01.flag = 1;
run02.flag = 0;
Thread thread01 = new Thread(run01);
Thread thread02 = new Thread(run02);
System.out.println("線程開始嘍!");
thread01.start();
thread02.start();
}
}
運行結果如下:
這樣就產生了死鎖,這是我們過多的使用同步而產生的。我們在java中使用synchonized的時候要考慮這個問題,如何解決死鎖,大家可以從死鎖的四個條件去解決,只要破壞了一個必要條件,那么我們的死鎖就解決了。在java中使用多線程的時候一定要考慮是否有死鎖的問題哦。