亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

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

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的接口,它工作的是兩個(gè)對象,這兩個(gè)對象向?qū)Ψ綄で笏梨i而且都在使用同步阻塞。

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

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

當(dāng)我執(zhí)行上面的程序時(shí),就產(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.

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

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

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

避免死鎖

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

避免嵌套封鎖:這是死鎖最主要的原因的,如果你已經(jīng)有一個(gè)資源了就要避免封鎖另一個(gè)資源。如果你運(yùn)行時(shí)只有一個(gè)對象封鎖,那是幾乎不可能出現(xiàn)一個(gè)死鎖局面的。例如,這里是另一個(gè)運(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)域中的一個(gè)感興趣,那我們應(yīng)當(dāng)封鎖住那個(gè)特殊的領(lǐng)域而并非完全的對象。

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

相關(guān)文章

  • java中List集合及其實(shí)現(xiàn)類的方法詳解

    java中List集合及其實(shí)現(xiàn)類的方法詳解

    本篇文章給大家?guī)淼膬?nèi)容是關(guān)于java中List集合及其實(shí)現(xiàn)類的方法介紹(附代碼),有一定的參考價(jià)值,有需要的朋友可以參考一下,希望對你有所幫助。下面我們就來學(xué)習(xí)一下吧
    2019-06-06
  • Java行為型設(shè)計(jì)模式之策略模式詳解

    Java行為型設(shè)計(jì)模式之策略模式詳解

    策略模式屬于Java-設(shè)計(jì)模式中行為模式之一,該模式定義了一系列算法,并將每個(gè)算法封裝起來,使它們可以相互替換。本文將通過示例詳細(xì)講解這一模式,需要的可以參考一下
    2022-11-11
  • Java框架Quartz中API、Jobs和Trigger詳解

    Java框架Quartz中API、Jobs和Trigger詳解

    這篇文章主要介紹了Java框架Quartz中API、Jobs和Trigger詳解,JobDetail?對象是在將?job?加入?scheduler?時(shí),由客戶端程序(你的程序)創(chuàng)建的,它包含?job?的各種屬性設(shè)置,以及用于存儲?job?實(shí)例狀態(tài)信息的?JobDataMap,需要的朋友可以參考下
    2023-11-11
  • Java中的@Repeatable注解使用詳解

    Java中的@Repeatable注解使用詳解

    這篇文章主要介紹了Java中的@Repeatable注解使用詳解,@Repeatable注解是java8為了解決同一個(gè)注解不能重復(fù)在同一類/方法/屬性上使用的問題,本文提供了解決思路和部分實(shí)現(xiàn)代碼,需要的朋友可以參考下
    2024-02-02
  • Spring Boot 2.0快速構(gòu)建服務(wù)組件全步驟

    Spring Boot 2.0快速構(gòu)建服務(wù)組件全步驟

    這篇文章主要給大家介紹了關(guān)于Spring Boot 2.0快速構(gòu)建服務(wù)組件的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Spring Boot 2.0具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • Spring注解和同步鎖不能同步問題解決

    Spring注解和同步鎖不能同步問題解決

    這篇文章主要介紹了Spring注解和同步鎖不能同步問題解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • maven私服搭建的實(shí)現(xiàn)步驟

    maven私服搭建的實(shí)現(xiàn)步驟

    本文主要介紹了maven私服搭建的實(shí)現(xiàn)步驟,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • java 多線程饑餓現(xiàn)象的問題解決方法

    java 多線程饑餓現(xiàn)象的問題解決方法

    這篇文章主要介紹了java 多線程饑餓現(xiàn)象的問題解決方法的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • 最有價(jià)值的50道java面試題 適用于準(zhǔn)入職Java程序員

    最有價(jià)值的50道java面試題 適用于準(zhǔn)入職Java程序員

    這篇文章主要為大家分享了最有價(jià)值的50道java面試題,涵蓋內(nèi)容全面,包括數(shù)據(jù)結(jié)構(gòu)和算法相關(guān)的題目、經(jīng)典面試編程題等,對hashCode方法的設(shè)計(jì)、垃圾收集的堆和代進(jìn)行剖析,感興趣的小伙伴們可以參考一下
    2016-05-05
  • 談?wù)勛兞棵?guī)范的重要性

    談?wù)勛兞棵?guī)范的重要性

    下面小編就為大家?guī)硪黄務(wù)勛兞棵?guī)范的重要性。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-01-01

最新評論