搜尋

首頁  >  問答  >  主體

java - 多執行緒死鎖測試

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

<code>package test;

 

import java.text.DateFormat;

import java.text.SimpleDateFormat;

import java.util.Date;

import java.util.concurrent.TimeUnit;

 

/**

 * Created by rhwayfun on 16-4-3.

 */

public class ThreadTest {

 

    private static DateFormat format = new SimpleDateFormat("HH:mm:ss");

 

    public synchronized void tryOther(ThreadTest other) throws InterruptedException {

        System.out.println(Thread.currentThread().getName() + " enter tryOther method at " + format.format(new Date()));     

        System.out.println(Thread.currentThread().getName() + " tryOther method is about to invoke other method at " + format.format(new Date()));

        other.other();

    }

 

    public synchronized void other() throws InterruptedException {

        System.out.println(Thread.currentThread().getName() + " enter other method atatatatat " + format.format(new Date()));

    }

 

    public static void main(String[] args) throws InterruptedException {

        final ThreadTest d1 = new ThreadTest();

        final ThreadTest d2 = new ThreadTest();

 

        Thread t1 = new Thread(new Runnable() {

            public void run() {

                try {

                    d1.tryOther(d2);

                } catch (InterruptedException e) {

                    e.printStackTrace();

                }

            }

        }, "threadA");

 

        Thread t2 = new Thread(new Runnable() {

            public void run() {

                try {

                    d2.tryOther(d1);

                } catch (InterruptedException e) {

                    e.printStackTrace();

                }

            }

        }, "threadB");

 

        t1.start();

        //让threadA先运行一秒

        TimeUnit.SECONDS.sleep(1);

        t2.start();

 

    }

}</code>

如上,隨便找的產生死鎖的代碼,問題:
TimeUnit.SECONDS.sleep(1);加上這行後,不存在死鎖問題。sleep並不釋放鎖,為何這邊死鎖情況會消失。
輸出結果為:
threadA enter tryOther method at 15:37:39
threadA tryOther method is about to invoke other method at 15:37:39
threadA enter other method atatatatat 15:37:39
threadB enter tryOther method at 15:37:40
threadB tryOther method is about to invoke other method at 15:37:40
threadB enter other method atatatatat 15:37:40

注掉這行,正常死鎖。
輸出結果為:
threadB enter tryOther method at 15:37:10
threadA enter tryOther method at 15:37:10
threadB tryOther method is about to invoke other method at 15:37:10
threadA tryOther method is about to invoke other method at 15:37:10

阿神阿神2820 天前734

全部回覆(3)我來回復

  • 大家讲道理

    大家讲道理2017-04-18 10:56:48

    線程A拿到tryOther鎖但是他還要得到other的鎖
    線程B拿到tryOther的鎖但是他還要拿到other的鎖
    有可能A剛剛釋放鎖B也剛剛釋放tryOther的鎖.
    此時但他們同時都想要取得other的鎖此時誰也不讓誰發生死鎖
    解決方法讓兩個線程不要同時去搶第二把鎖.讓A停一會
    但是如果你把時間調成納秒級多次嘗試也會發生死鎖
    不建議這樣預防死鎖.如果並發量高的情況下.

    回覆
    0
  • 阿神

    阿神2017-04-18 10:56:48

    雙方在爭同一把鎖,不會死鎖啊

    回覆
    0
  • PHPz

    PHPz2017-04-18 10:56:48

    自己突然知道為什麼了,懶得刪帖了。寫下我的看法,如果有錯,歡迎指正,輕噴
    在沒有sleep時,a線程啟動,完成tryOther方法,釋放鎖並去執行other方法,此時b獲得鎖執行tryOther方法,
    此時a在other方法中所需資源被b執行緒鎖住,b執行完tryOther後需要取得a資源,由此產生死鎖。

    加上sleep後。在a執行tryOther方法釋放鎖,此時b執行緒並沒有執行,此時順利取得other鎖。 2s後b線程執行,
    無死鎖環境。

    回覆
    0
  • 取消回覆