標籤:
在實際編程中,要盡量避免出現死結的情況,但是讓你故意寫一個死結的程式時似乎也不太簡單(有公司會出這樣的面試題),以下是一個簡單的死結例子。
線程的同步化可能會造成死結,死結發生在兩個線程相互持有對方正在等待的東西(實際是兩個線程共用的東西)。只要有兩個線程和兩個對象就可能產生死結。
package sxh.java.lock;/*** 一個簡單的死結類* 當DeadLock類的對象flag==1時(td1),先鎖定o1,睡眠500毫秒* 而td1在睡眠的時候另一個flag==0的對象(td2)線程啟動,先鎖定o2,睡眠500毫秒* td1睡眠結束後需要鎖定o2才能繼續執行,而此時o2已被td2鎖定;* td2睡眠結束後需要鎖定o1才能繼續執行,而此時o1已被td1鎖定;* td1、td2相互等待,都需要得到對方鎖定資源才能繼續執行,從而死結。*/public class DeadLock implements Runnable {public int flag = 1;//靜態對象是類的所有對象共用的private static Object o1 = new Object(), o2 = new Object();@Overridepublic void run() {System.out.println("flag=" + flag);if (flag == 1) {synchronized (o1) {try {Thread.sleep(500);} catch (Exception e) {e.printStackTrace();}synchronized (o2) {System.out.println("1");}}}if (flag == 0) {synchronized (o2) {try {Thread.sleep(500);} catch (Exception e) {e.printStackTrace();}synchronized (o1) {System.out.println("0");}}}}public static void main(String[] args) {DeadLock td1 = new DeadLock();DeadLock td2 = new DeadLock();td1.flag = 1;td2.flag = 0;//td1,td2都處於可執行狀態,但JVM線程調度先執行哪個線程是不確定的。//td2的run()可能在td1的run()之前運行new Thread(td1).start();new Thread(td2).start();}}
一個簡單的java死結樣本