zoukankan      html  css  js  c++  java
  • 线程死锁

    原创转载请注明出处:https://www.cnblogs.com/agilestyle/p/11424647.html

    死锁:一组互相竞争资源的线程因互相等待,导致“永久”阻塞的现象。 

    解决死锁,要么重启,要么规避

    那如何避免死锁呢?要避免死锁就需要分析死锁发生的条件,只有以下这四个条件都发生时才会出现死锁:

    1. 互斥,共享资源 X 和 Y 只能被一个线程占用;
    2. 占有且等待,线程 T1 已经取得共享资源 X,在等待共享资源 Y 的时候,不释放共享资源 X;
    3. 不可抢占,其他线程不能强行抢占线程 T1 占有的资源;
    4. 循环等待,线程 T1 等待线程 T2 占有的资源,线程 T2 等待线程 T1 占有的资源,就是循环等待。

    反过来分析,也就是说只要破坏其中一个,就可以成功避免死锁的发生。 

    模拟一个死锁的程序

     1 package org.fool.test;
     2 
     3 import java.util.concurrent.TimeUnit;
     4 import java.util.concurrent.locks.Lock;
     5 import java.util.concurrent.locks.ReentrantLock;
     6 
     7 public class DeadLockTest {
     8     private static Lock lockA = new ReentrantLock();
     9     private static Lock lockB = new ReentrantLock();
    10 
    11     public static void main(String[] args) {
    12         new Thread(new Runnable() {
    13             @Override
    14             public void run() {
    15                 try {
    16                     lockA.lock();
    17                     System.out.println("=====Thread A outer invoked...=====");
    18                     TimeUnit.SECONDS.sleep(3);
    19                     try {
    20                         lockB.lock();
    21                         System.out.println("=====Thread A inner invoked...=====");
    22                     } finally {
    23                         lockB.unlock();
    24                     }
    25                 } catch (InterruptedException e) {
    26                     e.printStackTrace();
    27                 } finally {
    28                     lockA.unlock();
    29                 }
    30             }
    31         }, "Thread-A").start();
    32 
    33         new Thread(new Runnable() {
    34             @Override
    35             public void run() {
    36                 try {
    37                     lockB.lock();
    38                     System.out.println("=====Thread B outer invoked...=====");
    39                     TimeUnit.SECONDS.sleep(3);
    40                     try {
    41                         lockA.lock();
    42                         System.out.println("=====Thread B inner invoked...=====");
    43                     } finally {
    44                         lockA.unlock();
    45                     }
    46                 } catch (InterruptedException e) {
    47                     e.printStackTrace();
    48                 } finally {
    49                     lockB.unlock();
    50                 }
    51             }
    52         }, "Thread-B").start();
    53     }
    54 
    55 }

    打包成可执行jar包后,运行java -jar hello-deadlock-1.0-SNAPSHOT.jar

    ps -ef | grep java 找出对应的pid,使用jstack打出堆栈信息

      1 2019-04-25 15:49:30  
      2 Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.121-b13 mixed mode):  
      3   
      4 "Attach Listener" #13 daemon prio=9 os_prio=31 tid=0x00007fb881058800 nid=0x1407 waiting on condition [0x0000000000000000]  
      5    java.lang.Thread.State: RUNNABLE  
      6   
      7 "DestroyJavaVM" #12 prio=5 os_prio=31 tid=0x00007fb882802000 nid=0x1c03 waiting on condition [0x0000000000000000]  
      8    java.lang.Thread.State: RUNNABLE  
      9   
     10 "Thread-B" #11 prio=5 os_prio=31 tid=0x00007fb883807000 nid=0x5903 waiting on condition [0x0000700002f89000]  
     11    java.lang.Thread.State: WAITING (parking)  
     12     at sun.misc.Unsafe.park(Native Method)  
     13     - parking to wait for  <0x000000076abdaa00> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)  
     14     at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)  
     15     at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)  
     16     at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:870)  
     17     at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1199)  
     18     at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:209)  
     19     at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:285)  
     20     at org.fool.test.DeadLockTest$2.run(DeadLockTest.java:41)  
     21     at java.lang.Thread.run(Thread.java:745)  
     22   
     23 "Thread-A" #10 prio=5 os_prio=31 tid=0x00007fb8800a7800 nid=0x5703 waiting on condition [0x0000700002e86000]  
     24    java.lang.Thread.State: WAITING (parking)  
     25     at sun.misc.Unsafe.park(Native Method)  
     26     - parking to wait for  <0x000000076abdaa30> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)  
     27     at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)  
     28     at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)  
     29     at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:870)  
     30     at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1199)  
     31     at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:209)  
     32     at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:285)  
     33     at org.fool.test.DeadLockTest$1.run(DeadLockTest.java:20)  
     34     at java.lang.Thread.run(Thread.java:745)  
     35   
     36 "Service Thread" #9 daemon prio=9 os_prio=31 tid=0x00007fb882051000 nid=0x5303 runnable [0x0000000000000000]  
     37    java.lang.Thread.State: RUNNABLE  
     38   
     39 "C1 CompilerThread3" #8 daemon prio=9 os_prio=31 tid=0x00007fb880009800 nid=0x5103 waiting on condition [0x0000000000000000]  
     40    java.lang.Thread.State: RUNNABLE  
     41   
     42 "C2 CompilerThread2" #7 daemon prio=9 os_prio=31 tid=0x00007fb881044000 nid=0x4f03 waiting on condition [0x0000000000000000]  
     43    java.lang.Thread.State: RUNNABLE  
     44   
     45 "C2 CompilerThread1" #6 daemon prio=9 os_prio=31 tid=0x00007fb881043000 nid=0x4d03 waiting on condition [0x0000000000000000]  
     46    java.lang.Thread.State: RUNNABLE  
     47   
     48 "C2 CompilerThread0" #5 daemon prio=9 os_prio=31 tid=0x00007fb882025800 nid=0x4b03 waiting on condition [0x0000000000000000]  
     49    java.lang.Thread.State: RUNNABLE  
     50   
     51 "Signal Dispatcher" #4 daemon prio=9 os_prio=31 tid=0x00007fb88200c800 nid=0x4903 runnable [0x0000000000000000]  
     52    java.lang.Thread.State: RUNNABLE  
     53   
     54 "Finalizer" #3 daemon prio=8 os_prio=31 tid=0x00007fb880858000 nid=0x3903 in Object.wait() [0x000070000266e000]  
     55    java.lang.Thread.State: WAITING (on object monitor)  
     56     at java.lang.Object.wait(Native Method)  
     57     - waiting on <0x000000076ab08ec8> (a java.lang.ref.ReferenceQueue$Lock)  
     58     at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)  
     59     - locked <0x000000076ab08ec8> (a java.lang.ref.ReferenceQueue$Lock)  
     60     at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)  
     61     at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)  
     62   
     63 "Reference Handler" #2 daemon prio=10 os_prio=31 tid=0x00007fb880855800 nid=0x3703 in Object.wait() [0x000070000256b000]  
     64    java.lang.Thread.State: WAITING (on object monitor)  
     65     at java.lang.Object.wait(Native Method)  
     66     - waiting on <0x000000076ab06b68> (a java.lang.ref.Reference$Lock)  
     67     at java.lang.Object.wait(Object.java:502)  
     68     at java.lang.ref.Reference.tryHandlePending(Reference.java:191)  
     69     - locked <0x000000076ab06b68> (a java.lang.ref.Reference$Lock)  
     70     at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)  
     71   
     72 "VM Thread" os_prio=31 tid=0x00007fb881002800 nid=0x3503 runnable  
     73   
     74 "GC task thread#0 (ParallelGC)" os_prio=31 tid=0x00007fb880014800 nid=0x2503 runnable  
     75   
     76 "GC task thread#1 (ParallelGC)" os_prio=31 tid=0x00007fb880015800 nid=0x2703 runnable  
     77   
     78 "GC task thread#2 (ParallelGC)" os_prio=31 tid=0x00007fb880016000 nid=0x2903 runnable  
     79   
     80 "GC task thread#3 (ParallelGC)" os_prio=31 tid=0x00007fb880016800 nid=0x2b03 runnable  
     81   
     82 "GC task thread#4 (ParallelGC)" os_prio=31 tid=0x00007fb881001000 nid=0x2d03 runnable  
     83   
     84 "GC task thread#5 (ParallelGC)" os_prio=31 tid=0x00007fb881002000 nid=0x2f03 runnable  
     85   
     86 "GC task thread#6 (ParallelGC)" os_prio=31 tid=0x00007fb880800800 nid=0x3103 runnable  
     87   
     88 "GC task thread#7 (ParallelGC)" os_prio=31 tid=0x00007fb880801000 nid=0x3303 runnable  
     89   
     90 "VM Periodic Task Thread" os_prio=31 tid=0x00007fb880828800 nid=0x5503 waiting on condition  
     91   
     92 JNI global references: 6  
     93   
     94   
     95 Found one Java-level deadlock:  
     96 =============================  
     97 "Thread-B":  
     98   waiting for ownable synchronizer 0x000000076abdaa00, (a java.util.concurrent.locks.ReentrantLock$NonfairSync),  
     99   which is held by "Thread-A"  
    100 "Thread-A":  
    101   waiting for ownable synchronizer 0x000000076abdaa30, (a java.util.concurrent.locks.ReentrantLock$NonfairSync),  
    102   which is held by "Thread-B"  
    103   
    104 Java stack information for the threads listed above:  
    105 ===================================================  
    106 "Thread-B":  
    107     at sun.misc.Unsafe.park(Native Method)  
    108     - parking to wait for  <0x000000076abdaa00> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)  
    109     at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)  
    110     at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)  
    111     at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:870)  
    112     at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1199)  
    113     at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:209)  
    114     at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:285)  
    115     at org.fool.test.DeadLockTest$2.run(DeadLockTest.java:41)  
    116     at java.lang.Thread.run(Thread.java:745)  
    117 "Thread-A":  
    118     at sun.misc.Unsafe.park(Native Method)  
    119     - parking to wait for  <0x000000076abdaa30> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)  
    120     at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)  
    121     at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)  
    122     at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:870)  
    123     at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1199)  
    124     at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:209)  
    125     at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:285)  
    126     at org.fool.test.DeadLockTest$1.run(DeadLockTest.java:20)  
    127     at java.lang.Thread.run(Thread.java:745)  
    128   
    129 Found 1 deadlock.

    Note:

    tid: java线程ID 

    nid: native线程ID

  • 相关阅读:
    【8-21】java学习笔记03
    【每天一点点】
    【8-20】java学习笔记02
    【8-19】java学习笔记01
    【8-18】JS学习01
    【8-17】HTML测试
    Selenium之WebDriverWait
    Selenium之XPATH定位方法
    Fiddler用法
    微服务架构系统的测试
  • 原文地址:https://www.cnblogs.com/agilestyle/p/11424647.html
Copyright © 2011-2022 走看看