国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > Java > 正文

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

2024-07-14 08:42:56
字體:
來源:轉載
供稿:網友

本文介紹了Java中常見死鎖與活鎖的實例詳解,分享給大家,具體如下:

  • 順序死鎖:過度加鎖,導致由于執行順序的原因,互相持有對方正在等待的鎖
  • 資源死鎖:多個線程在相同的資源上發生等待

由于調用順序而產生的死鎖

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發現死鎖的痕跡

"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,從而形成了死鎖

線程饑餓死鎖

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();  }}

執行的輸出只有一行

in MyCallable

通過jstack觀察可以看到如下

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

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

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 措勤县| 东乡| 安化县| 吉隆县| 宁阳县| 平南县| 涪陵区| 康马县| 含山县| 二连浩特市| 磐石市| 海南省| 建昌县| 广州市| 日土县| 师宗县| 卓尼县| 尼勒克县| 亚东县| 平乐县| 滨州市| 阿巴嘎旗| 辽源市| 修文县| 北流市| 潜山县| 衢州市| 修文县| 突泉县| 资中县| 霸州市| 烟台市| 西藏| 西宁市| 观塘区| 广安市| 汝阳县| 中牟县| 阆中市| 永和县| 如皋市|