天天看點

Java死鎖

要避免死鎖,就要學會制造死鎖,是以要先了解下問什麼會出現死鎖。

在多線程并發條件下,多線程互相等待搶占資源。

而恰好A線程要擷取B線程持有的鎖 1,B線程要擷取A線程持久的鎖 2。如果B線程不釋放鎖,A線程則永遠擷取不到,但B線程先要釋放鎖,就必須先拿到A線程持久的鎖,這豈不是很繞。這就是代碼中和資料庫中很常見的死鎖。下面用java寫一段:

package com.ws;

import org.junit.Test;

/**
 * Created by wushuang
 */
public class DeadLock {

    @Test
    public void junitTest() {
        new Thread(new Runnable() {
            public void run() {
                test();
            }
        }).start();

        new Thread(new Runnable() {
            public void run() {
                test();
            }
        }).start();
    }

    A a = new A();  //公用對象 作為被搶占的鎖對象存在
    B b = new B();
    public void test() {
        int i = 0;
        while (true) {
            System.out.println("ThreadName " + Thread.currentThread().getName());
            if (i % 2 == 0) {
                synchronized (a) {
                    System.out.println("【First】已 lock [A]對象  準備lock B");
                    synchronized (b) {
                        System.out.println("【First】已 lock [B]對象");
                    }
                }
            } else {
                synchronized (b) {
                    System.out.println("【Second】已 lock [B]對象  準備lock A");
                    synchronized (a) {
                        System.out.println("【Second】已 lock [A]對象");
                    }
                }
            }
            i += 1;
        }
    }
}      

輸出結果如下:

Java死鎖

可以看到兩個線程發生死鎖,Thread-0 lock了B  準備擷取A,而此時Thread-1 lock了A  準備擷取B,互相等待,導緻死鎖(至于A B是什麼不重要,他們可以代表兩個資源或者兩把鎖)