1. 程式人生 > 其它 >實現一個執行緒死鎖

實現一個執行緒死鎖

要想實現執行緒死鎖,首先要清楚執行緒死鎖的四個條件

  1. 互斥條件:一個資源每次只能被一個程序使用,即在一段時間內某資源僅為一個程序所使用。此時如果有其它程序請求該資源,則請求程序只能等待。
  2. 請求和保持條件:程序中已經保持了至少一個資源,但又提出了新的資源請求,而該資源已經被其它程序佔用,此時請求程序被阻塞,但對它自己已經獲得的資源保持不放。
  3. 不可剝奪條件:程序未使用完的資源在未使用完畢之前,不能被其它程序強行奪走,即只能由獲得該資源的程序自己來釋放
  4. 迴圈等待條件:若干程序間形成首尾相接迴圈等待資源的關係。在發生死鎖時必然存在一個程序等待列隊{P1, P2, ..., Pn},其中P1等待P2佔有的資源,P2等待P3佔有的資源....,Pn等待P1佔有的資源。形成一個程序等待環路,環路中每一個程序所佔有的資源同時被同一個申請。
class MyThread extends Thread{
  //類屬性被所有例項共享
  static Object o1 = new Object();
  static Object o2 = new Object();
  
  public MyThread(int flag){
    this.flag = flag;
  }
  
  @Override
  public void run(){
    if(flag == 0){
      // 若flag==0 鎖住o1
      synchronized(o1){
        System.out.println(flag + "鎖住了o1");
        // 執行緒睡眠,讓出cpu,但不釋放鎖
        Thread.sleep(1000);
        // 請求鎖物件o2,但o2被flag==1佔用
        synchronized(o2){
          System.out.println(flag + "鎖住了o2");
        }
      }
      // 執行緒死鎖,無法繼續執行
      System.out.println(flag + "釋放了o1和o2");
    }
    
    if(flag == 1){
      // 若flag==1 鎖住o2
      synchronized(o2){
        System.out.println(flag + "鎖住了o2");
        // 執行緒睡眠,讓出cpu,但不釋放鎖
        Thread.sleep(1000);
        // 請求鎖物件o1,但o1被flag==0佔用
        synchronized(o1){
          System.out.println(flag + "鎖住了o1");
        }
        // 執行緒死鎖,無法繼續執行
        System.out.println(flag + "釋放了o1和o2");
      }
    }
  }
}

public class ThreadDeadLock{
  public static void main(String[] args){
    MyThread t1 = new MyThread(0);
    MyThread t2 = new MyThread(1);
    t1.start();
    t2.start();
  }
}