1. 程式人生 > >多執行緒程式設計(一)——寫一個簡單的死鎖

多執行緒程式設計(一)——寫一個簡單的死鎖

(整個九月忙著找工作,好多收穫,好多遺憾,最終結局還可以接受,技術路還很遠,再接再厲!面去哪兒網時,寫慣了演算法的我突然讓寫了幾個多執行緒程式設計,有點矇蔽,最近好好整理一下)

死鎖發生的原因:

1、系統資源有限

2、程序或執行緒推進順序不恰當

3、資源分配不當

死鎖發生的四個條件:

1、互斥條件:一份資源每次只能被一個程序或執行緒使用(在Java中一般體現為,一個物件鎖只能被一個執行緒持有)

2、請求與保持條件:一個程序或執行緒在等待請求資源被釋放時,不釋放已佔有資源

3、不可剝奪條件:一個程序或執行緒已經獲得的資源不能被其他程序或執行緒強行剝奪

4、迴圈等待條件:形成一種迴圈等待的場景

下面看程式碼:

public class A {
	public synchronized void waitMethod(B b) throws InterruptedException{
		System.out.println(Thread.currentThread().getName() + ":正在執行a的等待方法,持有a的物件鎖");
		Thread.sleep(2000L);
		System.out.println(Thread.currentThread().getName() + ":試圖呼叫b的死鎖方法,嘗試獲取b的物件鎖");
		b.deadLockMethod();
	}
	
	public synchronized void deadLockMethod(){
		System.out.println(Thread.currentThread().getName() + ":正在執行a的死鎖方法,持有a的物件鎖");
	}
}
public class B {
	public synchronized void waitMethod(A a) throws InterruptedException{
		System.out.println(Thread.currentThread().getName() + ":正在執行b的等待方法,持有b的物件鎖");
		Thread.sleep(2000L);
		System.out.println(Thread.currentThread().getName() + ":試圖呼叫a的死鎖方法,嘗試獲取a的物件鎖");
		a.deadLockMethod();
	}
	
	public synchronized void deadLockMethod(){
		System.out.println(Thread.currentThread().getName() + ":正在執行B的死鎖方法,持有B的物件鎖");
	}
}
public class TestDeadLock implements Runnable {

	A a = new A();
	B b = new B();
	
	public void init() throws InterruptedException{
		Thread.currentThread().setName("主執行緒");
		a.waitMethod(b);
	}
	
	@Override
	public void run() {
		Thread.currentThread().setName("副執行緒");
		try {
			b.waitMethod(a);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) throws InterruptedException{
		TestDeadLock testDeadLock = new TestDeadLock();
		Thread thread = new Thread(testDeadLock);
		thread.start();	
		testDeadLock.init();
	}
}
通過sleep()方法,可以實現主執行緒持有a的物件鎖並請求b的物件鎖、副執行緒持有b的物件鎖並請求a的物件鎖的場景,即發生死鎖。

效果如下: