實現一個執行緒死鎖
阿新 • • 發佈:2021-11-10
要想實現執行緒死鎖,首先要清楚執行緒死鎖的四個條件
- 互斥條件:一個資源每次只能被一個程序使用,即在一段時間內某資源僅為一個程序所使用。此時如果有其它程序請求該資源,則請求程序只能等待。
- 請求和保持條件:程序中已經保持了至少一個資源,但又提出了新的資源請求,而該資源已經被其它程序佔用,此時請求程序被阻塞,但對它自己已經獲得的資源保持不放。
- 不可剝奪條件:程序未使用完的資源在未使用完畢之前,不能被其它程序強行奪走,即只能由獲得該資源的程序自己來釋放
- 迴圈等待條件:若干程序間形成首尾相接迴圈等待資源的關係。在發生死鎖時必然存在一個程序等待列隊{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(); } }