最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java死鎖_動力節(jié)點(diǎn)Java學(xué)院整理

 更新時間:2017年06月02日 14:56:02   投稿:mrr  
死鎖是兩個甚至多個線程被永久阻塞時的一種運(yùn)行局面,這種局面的生成伴隨著至少兩個線程和兩個或者多個資源。在這里我已寫好一個簡單的程序,它將會引起死鎖方案然后我們就會明白如何分析它

死鎖是兩個甚至多個線程被永久阻塞時的一種運(yùn)行局面,這種局面的生成伴隨著至少兩個線程和兩個或者多個資源。在這里我已寫好一個簡單的程序,它將會引起死鎖方案然后我們就會明白如何分析它。

Java死鎖范例

ThreadDeadlock.java

package com.bjpowernode.threads;
public class ThreadDeadlock {
  public static void main(String[] args) throws InterruptedException {
    Object obj1 = new Object();
    Object obj2 = new Object();
    Object obj3 = new Object();
    Thread t1 = new Thread(new SyncThread(obj1, obj2), "t1");
    Thread t2 = new Thread(new SyncThread(obj2, obj3), "t2");
    Thread t3 = new Thread(new SyncThread(obj3, obj1), "t3");
    t1.start();
    Thread.sleep(5000);
    t2.start();
    Thread.sleep(5000);
    t3.start();
  }
}
class SyncThread implements Runnable{
  private Object obj1;
  private Object obj2;
  public SyncThread(Object o1, Object o2){
    this.obj1=o1;
    this.obj2=o2;
  }
  @Override
  public void run() {
    String name = Thread.currentThread().getName();
    System.out.println(name + " acquiring lock on "+obj1);
    synchronized (obj1) {
     System.out.println(name + " acquired lock on "+obj1);
     work();
     System.out.println(name + " acquiring lock on "+obj2);
     synchronized (obj2) {
      System.out.println(name + " acquired lock on "+obj2);
      work();
    }
     System.out.println(name + " released lock on "+obj2);
    }
    System.out.println(name + " released lock on "+obj1);
    System.out.println(name + " finished execution.");
  }
  private void work() {
    try {
      Thread.sleep(30000);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }
}

在上面的程序中同步線程正完成Runnable的接口,它工作的是兩個對象,這兩個對象向?qū)Ψ綄で笏梨i而且都在使用同步阻塞。

在主函數(shù)中,我使用了三個為同步線程運(yùn)行的線程,而且在其中每個線程中都有一個可共享的資源。

這些線程以向第一個對象獲取封鎖這種方式運(yùn)行。但是當(dāng)它試著像第二個對象獲取封鎖時,它就會進(jìn)入等待狀態(tài),因?yàn)樗呀?jīng)被另一個線程封鎖住了。這樣,在線程引起死鎖的過程中,就形成了一個依賴于資源的循環(huán)。

當(dāng)我執(zhí)行上面的程序時,就產(chǎn)生了輸出,但是程序卻因?yàn)樗梨i無法停止。

 t1 acquiring lock on java.lang.Object@6d9dd520
t1 acquired lock on java.lang.Object@6d9dd520
t2 acquiring lock on java.lang.Object@22aed3a5
t2 acquired lock on java.lang.Object@22aed3a5
t3 acquiring lock on java.lang.Object@218c2661
t3 acquired lock on java.lang.Object@218c2661
t1 acquiring lock on java.lang.Object@22aed3a5
t2 acquiring lock on java.lang.Object@218c2661
t3 acquiring lock on java.lang.Object@6d9dd520

在此我們可以清楚地在輸出結(jié)果中辨認(rèn)出死鎖局面,但是在我們實(shí)際生活所用的應(yīng)用中,發(fā)現(xiàn)死鎖并將它排除是非常難的。

分析死鎖

 2012-12-27 19:08:34
Full thread dump Java HotSpot(TM) 64-Bit Server VM (23.5-b02 mixed mode):
 "Attach Listener" daemon prio=5 tid=0x00007fb0a2814000 nid=0x4007 waiting on condition [0x0000000000000000]
  java.lang.Thread.State: RUNNABLE
"DestroyJavaVM" prio=5 tid=0x00007fb0a2801000 nid=0x1703 waiting on condition [0x0000000000000000]
  java.lang.Thread.State: RUNNABLE
"t3" prio=5 tid=0x00007fb0a204b000 nid=0x4d07 waiting for monitor entry [0x000000015d971000]
  java.lang.Thread.State: BLOCKED (on object monitor)
  at com.bjpowernode.threads.SyncThread.run(ThreadDeadlock.java:41)
  - waiting to lock <0x000000013df2f658> (a java.lang.Object)
  - locked <0x000000013df2f678> (a java.lang.Object)
  at java.lang.Thread.run(Thread.java:722)
"t2" prio=5 tid=0x00007fb0a1073000 nid=0x4207 waiting for monitor entry [0x000000015d209000]
  java.lang.Thread.State: BLOCKED (on object monitor)
  at com.bjpowernode.threads.SyncThread.run(ThreadDeadlock.java:41)
  - waiting to lock <0x000000013df2f678> (a java.lang.Object)
  - locked <0x000000013df2f668> (a java.lang.Object)
  at java.lang.Thread.run(Thread.java:722)
"t1" prio=5 tid=0x00007fb0a1072000 nid=0x5503 waiting for monitor entry [0x000000015d86e000]
  java.lang.Thread.State: BLOCKED (on object monitor)
  at com.bjpowernode.threads.SyncThread.run(ThreadDeadlock.java:41)
  - waiting to lock <0x000000013df2f668> (a java.lang.Object)
  - locked <0x000000013df2f658> (a java.lang.Object)
  at java.lang.Thread.run(Thread.java:722)
"Service Thread" daemon prio=5 tid=0x00007fb0a1038000 nid=0x5303 runnable [0x0000000000000000]
  java.lang.Thread.State: RUNNABLE
"C2 CompilerThread1" daemon prio=5 tid=0x00007fb0a1037000 nid=0x5203 waiting on condition [0x0000000000000000]
  java.lang.Thread.State: RUNNABLE
"C2 CompilerThread0" daemon prio=5 tid=0x00007fb0a1016000 nid=0x5103 waiting on condition [0x0000000000000000]
  java.lang.Thread.State: RUNNABLE
"Signal Dispatcher" daemon prio=5 tid=0x00007fb0a4003000 nid=0x5003 runnable [0x0000000000000000]
  java.lang.Thread.State: RUNNABLE
"Finalizer" daemon prio=5 tid=0x00007fb0a4800000 nid=0x3f03 in Object.wait() [0x000000015d0c0000]
  java.lang.Thread.State: WAITING (on object monitor)
  at java.lang.Object.wait(Native Method)
  - waiting on <0x000000013de75798> (a java.lang.ref.ReferenceQueue$Lock)
  at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:135)
  - locked <0x000000013de75798> (a java.lang.ref.ReferenceQueue$Lock)
  at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:151)
  at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:177)
"Reference Handler" daemon prio=5 tid=0x00007fb0a4002000 nid=0x3e03 in Object.wait() [0x000000015cfbd000]
  java.lang.Thread.State: WAITING (on object monitor)
  at java.lang.Object.wait(Native Method)
  - waiting on <0x000000013de75320> (a java.lang.ref.Reference$Lock)
  at java.lang.Object.wait(Object.java:503)
  at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133)
  - locked <0x000000013de75320> (a java.lang.ref.Reference$Lock)
"VM Thread" prio=5 tid=0x00007fb0a2049800 nid=0x3d03 runnable 
"GC task thread#0 (ParallelGC)" prio=5 tid=0x00007fb0a300d800 nid=0x3503 runnable 
"GC task thread#1 (ParallelGC)" prio=5 tid=0x00007fb0a2001800 nid=0x3603 runnable 
"GC task thread#2 (ParallelGC)" prio=5 tid=0x00007fb0a2003800 nid=0x3703 runnable 
"GC task thread#3 (ParallelGC)" prio=5 tid=0x00007fb0a2004000 nid=0x3803 runnable 
"GC task thread#4 (ParallelGC)" prio=5 tid=0x00007fb0a2005000 nid=0x3903 runnable 
"GC task thread#5 (ParallelGC)" prio=5 tid=0x00007fb0a2005800 nid=0x3a03 runnable 
"GC task thread#6 (ParallelGC)" prio=5 tid=0x00007fb0a2006000 nid=0x3b03 runnable 
"GC task thread#7 (ParallelGC)" prio=5 tid=0x00007fb0a2006800 nid=0x3c03 runnable 
"VM Periodic Task Thread" prio=5 tid=0x00007fb0a1015000 nid=0x5403 waiting on condition 
JNI global references: 114
Found one Java-level deadlock:
=============================
"t3":
 waiting to lock monitor 0x00007fb0a1074b08 (object 0x000000013df2f658, a java.lang.Object),
 which is held by "t1"
"t1":
 waiting to lock monitor 0x00007fb0a1010f08 (object 0x000000013df2f668, a java.lang.Object),
 which is held by "t2"
"t2":
 waiting to lock monitor 0x00007fb0a1012360 (object 0x000000013df2f678, a java.lang.Object),
 which is held by "t3"
Java stack information for the threads listed above:
===================================================
"t3":
  at com.bjpowernode.threads.SyncThread.run(ThreadDeadlock.java:41)
  - waiting to lock <0x000000013df2f658> (a java.lang.Object)
  - locked <0x000000013df2f678> (a java.lang.Object)
  at java.lang.Thread.run(Thread.java:722)
"t1":
  at com.bjpowernode.threads.SyncThread.run(ThreadDeadlock.java:41)
  - waiting to lock <0x000000013df2f668> (a java.lang.Object)
  - locked <0x000000013df2f658> (a java.lang.Object)
  at java.lang.Thread.run(Thread.java:722)
"t2":
  at com.bjpowernode.threads.SyncThread.run(ThreadDeadlock.java:41)
  - waiting to lock <0x000000013df2f678> (a java.lang.Object)
  - locked <0x000000013df2f668> (a java.lang.Object)
  at java.lang.Thread.run(Thread.java:722)
Found 1 deadlock.

這三個線程轉(zhuǎn)存的輸出清楚地說明了死鎖環(huán)境和線程,以及包含死鎖環(huán)境的資源。

為了分析死鎖,我們需要關(guān)注死鎖狀態(tài)的線程,然后資源再等待去封鎖,每一個資源都有一個獨(dú)特的ID,有了這個ID我們就能發(fā)現(xiàn)是哪一個進(jìn)程已經(jīng)封鎖住對象。舉個例子,線程“t3”正在等待封鎖0x000000013df2f658,但是它已經(jīng)被線程“t1”封鎖住了。

當(dāng)我們分析死鎖環(huán)境的時候,如果發(fā)現(xiàn)線程正在引起死鎖,這是我們就要改變代碼來避免死鎖的產(chǎn)生。

避免死鎖

有很多方針可供我們使用來避免死鎖的局面。

避免嵌套封鎖:這是死鎖最主要的原因的,如果你已經(jīng)有一個資源了就要避免封鎖另一個資源。如果你運(yùn)行時只有一個對象封鎖,那是幾乎不可能出現(xiàn)一個死鎖局面的。例如,這里是另一個運(yùn)行中沒有嵌套封鎖的run()方法,而且程序運(yùn)行沒有死鎖局面,運(yùn)行得很成功。

public void run() {
  String name = Thread.currentThread().getName();
  System.out.println(name + " acquiring lock on " + obj1);
  synchronized (obj1) {
    System.out.println(name + " acquired lock on " + obj1);
    work();
  }
  System.out.println(name + " released lock on " + obj1);
  System.out.println(name + " acquiring lock on " + obj2);
  synchronized (obj2) {
    System.out.println(name + " acquired lock on " + obj2);
    work();
  }
  System.out.println(name + " released lock on " + obj2);
 
  System.out.println(name + " finished execution.");
}

只對有請求的進(jìn)行封鎖:你應(yīng)當(dāng)只想你要運(yùn)行的資源獲取封鎖,比如在上述程序中我在封鎖的完全的對象資源。但是如果我們只對它所屬領(lǐng)域中的一個感興趣,那我們應(yīng)當(dāng)封鎖住那個特殊的領(lǐng)域而并非完全的對象。

避免無限期的等待:如果兩個線程正在等待對象結(jié)束,無限期的使用線程加入,如果你的線程必須要等待另一個線程的結(jié)束,若是等待進(jìn)程的結(jié)束加入最好準(zhǔn)備最長時間。

相關(guān)文章

  • guava中Multimap、HashMultimap用法小結(jié)

    guava中Multimap、HashMultimap用法小結(jié)

    這篇文章主要介紹了guava中Multimap、HashMultimap使用,Multimap它可以很簡單的實(shí)現(xiàn)一些功能,LinkedHashMultimap實(shí)現(xiàn)類與HashMultimap類的實(shí)現(xiàn)方法一樣,唯一的區(qū)別是LinkedHashMultimap保存了記錄的插入順序,本文就這些內(nèi)容講解的非常詳細(xì),需要的朋友參考下吧
    2022-05-05
  • Spring實(shí)現(xiàn)文件上傳功能

    Spring實(shí)現(xiàn)文件上傳功能

    本篇文章主要介紹了Spring實(shí)現(xiàn)文件上傳功能,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-01-01
  • Java 的抽象類原理與用法分析

    Java 的抽象類原理與用法分析

    這篇文章主要介紹了Java 的抽象類原理與用法,結(jié)合實(shí)例形式分析了java抽象類與接口的相關(guān)概念、原理、使用方法及操作注意事項,需要的朋友可以參考下
    2019-12-12
  • java根據(jù)不同的參數(shù)調(diào)用不同的實(shí)現(xiàn)類操作

    java根據(jù)不同的參數(shù)調(diào)用不同的實(shí)現(xiàn)類操作

    這篇文章主要介紹了java根據(jù)不同的參數(shù)調(diào)用不同的實(shí)現(xiàn)類操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • Spring?AOP簡介及統(tǒng)一處理

    Spring?AOP簡介及統(tǒng)一處理

    AOP面向切面編程,它是一種思想,它是對某一類事情的集中處理,本文給大家介紹Spring?AOP簡介及統(tǒng)一處理,感興趣的朋友跟隨小編一起看看吧
    2023-09-09
  • Java中LinkedHashSet的實(shí)現(xiàn)原理詳解

    Java中LinkedHashSet的實(shí)現(xiàn)原理詳解

    這篇文章主要介紹了Java中LinkedHasSet的實(shí)現(xiàn)原理詳解,LinkedHashSet?是具有可預(yù)知迭代順序的?Set?接口的哈希表和鏈接列表實(shí)現(xiàn),此實(shí)現(xiàn)與HashSet?的不同之處在于,后者維護(hù)著一個運(yùn)行于所有條目的雙重鏈接列表,需要的朋友可以參考下
    2023-09-09
  • Java容器ArrayList知識點(diǎn)總結(jié)

    Java容器ArrayList知識點(diǎn)總結(jié)

    本篇文章給大家分享了Java容器ArrayList的相關(guān)知識點(diǎn),對此有需要的朋友可以跟著學(xué)習(xí)參考下。
    2018-05-05
  • Mybatis-plus多租戶項目實(shí)戰(zhàn)進(jìn)階指南

    Mybatis-plus多租戶項目實(shí)戰(zhàn)進(jìn)階指南

    多租戶是一種軟件架構(gòu)技術(shù),在多用戶的環(huán)境下共有同一套系統(tǒng),并且要注意數(shù)據(jù)之間的隔離性,下面這篇文章主要給大家介紹了關(guān)于Mybatis-plus多租戶項目實(shí)戰(zhàn)進(jìn)階的相關(guān)資料,需要的朋友可以參考下
    2022-02-02
  • springboot?aop配合反射統(tǒng)一簽名驗(yàn)證實(shí)踐

    springboot?aop配合反射統(tǒng)一簽名驗(yàn)證實(shí)踐

    這篇文章主要介紹了springboot?aop配合反射統(tǒng)一簽名驗(yàn)證實(shí)踐,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • java打印表格 將ResultSet中的數(shù)據(jù)打印成表格問題

    java打印表格 將ResultSet中的數(shù)據(jù)打印成表格問題

    這篇文章主要介紹了java打印表格 將ResultSet中的數(shù)據(jù)打印成表格問題。具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-12-12

最新評論

鸡东县| 扎囊县| 甘谷县| 英德市| 胶州市| 通州区| 禹州市| 巫山县| 昆明市| 嘉祥县| 武汉市| 来宾市| 铜梁县| 五华县| 治县。| 浦北县| 南溪县| 开平市| 城口县| 克什克腾旗| 探索| 桂平市| 兰西县| 德钦县| 诸暨市| 曲水县| 左权县| 温宿县| 龙泉市| 凭祥市| 庆阳市| 行唐县| 怀远县| 陆丰市| 富川| 犍为县| 昌黎县| 岳西县| 偃师市| 和顺县| 遂昌县|