天天看點

Java中死鎖之代碼示範和檢測

簡介

本文将通過Java代碼示範一個死鎖程式,并用JDK自帶的工具

jstack

工具,來驗證下是否真正的有死鎖發生。

一.什麼是死鎖

兩個或兩個以上的線程,互相持有對方需要的資源,導緻這些線程一直處于“等待”(WAITING)狀态。

二.死鎖的代碼示範

本例示範兩個線程,互相競争對方的對象鎖,造成的死鎖。

public class DeadLock implements Runnable {

	int condition;
	static Object object1 = new Object();
	static Object object2 = new Object();

	public static void main(String[] args) {
		DeadLock deadLock1 = new DeadLock();
		DeadLock deadLock2 = new DeadLock();
		deadLock1.condition = 1;
		deadLock2.condition = 2;

		Thread t1 = new Thread(deadLock1);
		Thread t2 = new Thread(deadLock2);

		t1.start();
		t2.start();
	}

	@Override
	public void run() {
		System.out.println("目前是線程:" + condition);
		if (condition == 1) {
			synchronized (object1) {
				System.out.println("線程1" + "得到object1鎖");
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println("線程1,卡在下一行代碼");
				synchronized (object2) {
					System.out.println("列印出此行,表示線程1同時獲得兩把鎖");
				}
				System.out.println("線程1執行完畢");
			}
		}
		if (condition == 2) {
			synchronized (object2) {
				System.out.println("線程2" + "得到object2鎖");
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println("線程2,卡在下一行代碼");
				synchronized (object1) {
					System.out.println("列印出此行,表示線程2同時獲得兩把鎖");
				}
				System.out.println("線程2執行完畢");
			}
		}
	}
}

           

運作結果:

目前是線程:1
目前是線程:2
線程2得到object2鎖
線程1得到object1鎖
線程1,卡在下一行代碼
線程2,卡在下一行代碼
           

運作結果分析:

  1. 線程1持有了

    object1

    的鎖,線程2持有了

    object2

    的鎖。
  2. 然後線程1去競争

    object2

    鎖;線程2去競争

    object1

    鎖。
  3. 由于線程1并沒有釋放

    object1

    鎖,線程2也并沒有釋放

    object2

    鎖,是以會造成死鎖。

三.驗證是否真正死鎖

在指令行中輸入:

jps

,查到我們代碼程式的程序号為

6164

Java中死鎖之代碼示範和檢測

然後在指令行再輸入:

jstack -l 6164

,分析下程式狀态:

Java中死鎖之代碼示範和檢測

發現程式中出現了死鎖現象。

總結

明白了死鎖發生的機制,我們可以想辦法避免死鎖發生,第一種方法是注意加鎖順序,在上面的代碼執行個體中,我們隻要在兩個線程中,

對鎖的競争順序保持一緻(比如兩個線程都是先競争

object1

鎖,再競争

object2

鎖),那死鎖就不會出現了。第二種避免死鎖的方式是,

設定逾時時間,如果超過一定時間,自動釋放鎖。

在程式運作時,我們可以通過

jstack

工具,檢視程式運作狀态,是否有死鎖。

繼續閱讀