一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|JavaScript|易語言|

服務器之家 - 編程語言 - Java教程 - Java中常見死鎖與活鎖的實例詳解

Java中常見死鎖與活鎖的實例詳解

2021-06-17 11:14爬蜥 Java教程

這篇文章主要介紹了Java中常見死鎖與活鎖的實例詳解,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

本文介紹了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
public class test {
  object leftlock = new object();
  object rightlock = new object();
  public static void main(string[] args) {
    final test test = new test();
    thread a = new thread(new runnable() {
      @override      public void run() {
        int i=0;
        while (i<10)
        {
          test.leftright();
          i++;
        }
      }
    },"athread");
    thread b = new thread(new runnable() {
      @override      public void run() {
        int i=0;
        while (i<10)
        {
          test.rightleft();
          i++;
        }
      }
    },"bthread");
    a.start();
    b.start();
  }
 
  public void leftright(){
    synchronized (leftlock){
      system.out.println(thread.currentthread().getname()+":leftright:get left");
      synchronized (rightlock){
        system.out.println(thread.currentthread().getname()+":leftright:get right");
      }
    }
  }
 
  public void rightleft(){
    synchronized (rightlock){
      system.out.println(thread.currentthread().getname()+":rightleft: get right");
      synchronized (leftlock){
        system.out.println(thread.currentthread().getname()+":rightleft: get left");
      }
    }
  }
 
}

運行后輸出如下

athread:leftright:get left
bthread:rightleft: get right

可以通過jstack發現死鎖的痕跡

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
"bthread" prio=5 tid=0x00007fabb2001000 nid=0x5503 waiting for monitor entry [0x000000011d54b000]
  java.lang.thread.state: blocked (on object monitor)
  at main.locktest.test.rightleft(test.java:52)
  - waiting to lock <0x00000007aaee5748> (a java.lang.object)
  - locked <0x00000007aaee5758> (a java.lang.object)
  at main.locktest.test$2.run(test.java:30)
  at java.lang.thread.run(thread.java:745)
 
  locked ownable synchronizers:
  - none
 
"athread" prio=5 tid=0x00007fabb2801000 nid=0x5303 waiting for monitor entry [0x000000011d448000]
  java.lang.thread.state: blocked (on object monitor)
  at main.locktest.test.leftright(test.java:43)
  - waiting to lock <0x00000007aaee5758> (a java.lang.object)
  - locked <0x00000007aaee5748> (a java.lang.object)
  at main.locktest.test$1.run(test.java:19)
  at java.lang.thread.run(thread.java:745)
 
  locked ownable synchronizers:
  - none

可以看到bthread持有鎖0x00000007aaee5758,同時等待0x00000007aaee5748,然而恰好athread持有鎖0x00000007aaee5748并等待0x00000007aaee5758,從而形成了死鎖

線程饑餓死鎖

?
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
public class executorlock {
  private static executorservice single=executors.newsinglethreadexecutor();
  public static class anothercallable implements callable<string>{
 
    @override    public string call() throws exception {
      system.out.println("in anothercallable");
      return "annother success";
    }
  }
 
 
  public static class mycallable implements callable<string>{
 
    @override    public string call() throws exception {
      system.out.println("in mycallable");
      future<string> submit = single.submit(new anothercallable());
      return "success:"+submit.get();
    }
  }
  public static void main(string[] args) throws executionexception, interruptedexception {
    mycallable task = new mycallable();
    future<string> submit = single.submit(task);
    system.out.println(submit.get());
    system.out.println("over");
    single.shutdown();
  }
}

執行的輸出只有一行

?
1
in mycallable

通過jstack觀察可以看到如下

?
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
"main" prio=5 tid=0x00007fab3f000000 nid=0x1303 waiting on condition [0x0000000107d63000]
  java.lang.thread.state: waiting (parking)
  at sun.misc.unsafe.park(native method)
  - parking to wait for <0x00000007aaeed1d8> (a java.util.concurrent.futuretask)
  at java.util.concurrent.locks.locksupport.park(locksupport.java:186)
  at java.util.concurrent.futuretask.awaitdone(futuretask.java:425)
  at java.util.concurrent.futuretask.get(futuretask.java:187)
  at main.locktest.executorlock.main(executorlock.java:32)
  at sun.reflect.nativemethodaccessorimpl.invoke0(native method)
  at sun.reflect.nativemethodaccessorimpl.invoke(nativemethodaccessorimpl.java:57)
  at sun.reflect.delegatingmethodaccessorimpl.invoke(delegatingmethodaccessorimpl.java:43)
  at java.lang.reflect.method.invoke(method.java:606)
  at com.intellij.rt.execution.application.appmain.main(appmain.java:140)
 
  locked ownable synchronizers:
  - none
..
"pool-1-thread-1" prio=5 tid=0x00007fab3f835800 nid=0x5303 waiting on condition [0x00000001199ee000]
  java.lang.thread.state: waiting (parking)
  at sun.misc.unsafe.park(native method)
  - parking to wait for <0x00000007ab0f8698> (a java.util.concurrent.futuretask)
  at java.util.concurrent.locks.locksupport.park(locksupport.java:186)
  at java.util.concurrent.futuretask.awaitdone(futuretask.java:425)
  at java.util.concurrent.futuretask.get(futuretask.java:187)
  at main.locktest.executorlock$mycallable.call(executorlock.java:26)
  at main.locktest.executorlock$mycallable.call(executorlock.java:20)
  at java.util.concurrent.futuretask.run(futuretask.java:262)
  at java.util.concurrent.threadpoolexecutor.runworker(threadpoolexecutor.java:1145)
  at java.util.concurrent.threadpoolexecutor$worker.run(threadpoolexecutor.java:615)
  at java.lang.thread.run(thread.java:745)
 
  locked ownable synchronizers:
  - <0x00000007aaeed258> (a java.util.concurrent.threadpoolexecutor$worker)

主線程在等待一個futuretask完成,而線程池中一個線程也在等待一個futuretask完成。
從代碼實現可以看到,主線程往線程池中扔了一個任務a,任務a又往同一個線程池中扔了一個任務b,并等待b的完成,由于線程池中只有一個線程,這將導致b會被停留在阻塞隊列中,而a還得等待b的完成,這也就是互相等待導致了死鎖的反生

這種由于正在執行的任務線程都在等待其它工作隊列中的任務而阻塞的現象稱為 線程饑餓死鎖

活鎖

并未產生線程阻塞,但是由于某種問題的存在,導致無法繼續執行的情況。

1、消息重試。當某個消息處理失敗的時候,一直重試,但重試由于某種原因,比如消息格式不對,導致解析失敗,而它又被重試

這種時候一般是將不可修復的錯誤不要重試,或者是重試次數限定

2、相互協作的線程彼此響應從而修改自己狀態,導致無法執行下去。比如兩個很有禮貌的人在同一條路上相遇,彼此給對方讓路,但是又在同一條路上遇到了。互相之間反復的避讓下去

這種時候可以選擇一個隨機退讓,使得具備一定的隨機性

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:https://segmentfault.com/a/1190000017134766

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 午夜福利理论片高清在线 | 王小军怎么了最新消息 | 欧美一级视频在线 | 精品久久久噜噜噜久久7 | 动漫美女被褥吸奶漫画漫画 | 亚洲精品一区制服丝袜 | 国产一区视频在线免费观看 | 春宵福利网站在线观看 | 女人被男人躁得好爽免费视频 | 天天草b | 日本福利网 | 深夜在线观看网站 | 奶茶视频有容乃大 | 欧美高清在线不卡免费观看 | 欧美香蕉人人人人人人爱 | 亚洲视屏在线观看 | 能播放18xxx18女同 | 青草香蕉精品视频在线观看 | 麻豆视频免费在线观看 | chinesemature老女人 | 91日本在线观看亚洲精品 | 五月激激激综合网色播免费 | 国产免费资源高清小视频在线观看 | 美女被上漫画 | 久久成人a毛片免费观看网站 | 亚洲黄色大片 | 成人伊人青草久久综合网破解版 | 调教女警花穿环上班 | 欧美另类老女人 | 3d动漫美女物被遭强视频 | 猫咪色网 | 闺蜜的样子小说安沁在线阅读 | 男男羞羞视频网站国产 | 亚洲激情婷婷 | 娇小XXXXX第一次出血 | 国产精品视频免费观看 | 亚洲欧美专区精品久久 | 91色爱| 向日葵视频app下载18岁以下勿看 | 亚洲日本中文字幕天堂网 | 亚洲免费视频在线观看 |