1. 程式人生 > >java多線程中的死鎖情況讀書筆記

java多線程中的死鎖情況讀書筆記

bubuko 實例 syn 釋放 splay inf info sys 資源

多線程中的死鎖

在前面的分析中,我們知道一個對象可以用Synchronized方法或者其他的加鎖形式來防止別的任務在互斥還沒有釋放的時候就訪問這個對象。

試想一下這樣的情況:某個任務在等待另一個任務,而後者又在等待別的任務,這樣一直下去,知道這個鏈條的任務又在等待第一個任務釋放鎖,任務之間的互相等待形成了循環,沒有一個任務可以執行下去,最終所有的任務都阻塞,形成了死鎖

下面實例中,給出兩個靜態的資源,線程1先獲取obj1對象,在獲取obj2對象;線程2先獲取obj2對象,再獲取obj1對象

/**
 * 設計一個簡單的死鎖。
 * 首先明白什麽叫死鎖:兩個線程同時占有一個資源。
 * 
@author Xia * */ public class DreadThread implements Runnable{ //兩個靜態的資源 public static Object obj1 = new Object(); public static Object obj2 = new Object(); //標誌位,flag 等於不同的值時執行不同的代碼 public int flag = 1; //1 or 2 public DreadThread(int flag) { this.flag = flag; } @Override
public void run() { if(flag == 1) { //如果flag等於1,則該線程先獲取obj1,在獲取obj2 synchronized (obj1) { System.out.println("flag: " + flag + ", 鎖住了資源obj1"); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(
"flag: " + flag + ", 等待獲取資源obj2"); synchronized (obj2) { System.out.println("flag: " + flag + ", 獲得資源obj2"); } } } else if(flag == 2) { //如果flag等於2,則該線程先獲取obj2,再獲取obj1 synchronized (obj2) { System.out.println("flag: " + flag + ", 鎖住了資源obj2"); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("flag: " + flag + ", 等待獲取資源obj1"); synchronized (obj1) { System.out.println("flag: " + flag + ", 獲得資源obj1"); } } } } }

線程的測試類:

public class DreadThreadTest {
    public static void main(String[] args) {
        DreadThread thread1 = new DreadThread(1);
        DreadThread thread2 = new DreadThread(2);
        
        //啟動線程1
        new Thread(thread1).start();
        new Thread(thread2).start();
    }
}

效果:如圖所示,程序一直都無法結束。這就是所謂的死鎖。

技術分享圖片

java多線程中的死鎖情況讀書筆記