zoukankan      html  css  js  c++  java
  • java多线程基本概述(四)——死锁

    package mytask;
    
    public class Task {
        public static void main(String[] args) {
            DeadThread thread = new DeadThread();
            Thread t1 = new Thread(thread);
            t1.setName("a");
            Thread t2 = new Thread(thread);
            t2.setName("b");
            t1.start();
            t2.start();
        }    
    }
    
    class DeadThread implements Runnable{
        private String o1= new String("o1");
        private String o2 = new String("o2");
        @Override
        public void run() {
            if(Thread.currentThread().getName().equals("a")){
                synchronized(o1){
                    System.out.println("a thread  enter outer monitor o1....");
                    try{
                        Thread.sleep(3000);
                        System.out.println("a waiting for o2 monitor...");
                        synchronized(o2){
                            System.out.println("a thread enter inner monitr o2");
                        }
                    }catch(InterruptedException e){
                        e.printStackTrace();
                    }                
                }
            }else{
                synchronized(o2){
                    System.out.println("b thread  enter outer monitor o1....");
                    try{
                        Thread.sleep(3000);
                        System.out.println("b waiting for o1 monitor...");
                        synchronized(o1){
                            System.out.println("b thread enter inner monitr o1");
                        }
                    }catch(InterruptedException e){
                        e.printStackTrace();
                    }                
                }
            }
        }
        
    }

    输出结果:

    a thread  enter outer monitor o1....
    b thread  enter outer monitor o1....
    a waiting for o2 monitor...
    b waiting for o1 monitor...

    一致处于阻塞状态,可以通过jps命令查看信息得到

    8064 Task
    3832
    3388 Jps

    然后再执行 jstack -l 8064 

    得到信息

    Full thread dump Java HotSpot(TM) 64-Bit Server VM (20.6-b01 mixed mode):
    
    "DestroyJavaVM" prio=6 tid=0x000000000096c000 nid=0x494 waiting on condition [0x0000000000000000]
       java.lang.Thread.State: RUNNABLE
    
       Locked ownable synchronizers:
            - None
    
    "b" prio=6 tid=0x0000000006d66800 nid=0x548 waiting for monitor entry [0x000000000772f000]
       java.lang.Thread.State: BLOCKED (on object monitor)
            at mytask.DeadThread.run(Task.java:40)
            - waiting to lock <0x00000007c099b648> (a java.lang.String)
            - locked <0x00000007c099b668> (a java.lang.String)
            at java.lang.Thread.run(Thread.java:662)
    
       Locked ownable synchronizers:
            - None
    
    "a" prio=6 tid=0x0000000006d66000 nid=0x1354 waiting for monitor entry [0x000000000762f000]
       java.lang.Thread.State: BLOCKED (on object monitor)
            at mytask.DeadThread.run(Task.java:27)
            - waiting to lock <0x00000007c099b668> (a java.lang.String)
            - locked <0x00000007c099b648> (a java.lang.String)
            at java.lang.Thread.run(Thread.java:662)
    
       Locked ownable synchronizers:
            - None
    
    "Low Memory Detector" daemon prio=6 tid=0x00000000025bf000 nid=0x1890 runnable [0x0000000000000000]
       java.lang.Thread.State: RUNNABLE
    
       Locked ownable synchronizers:
            - None
    
    "C2 CompilerThread1" daemon prio=10 tid=0x00000000025b5800 nid=0x1bb8 waiting on condition [0x0000000000000000]
       java.lang.Thread.State: RUNNABLE
    
       Locked ownable synchronizers:
            - None
    
    "C2 CompilerThread0" daemon prio=10 tid=0x00000000025ac800 nid=0x1ee8 waiting on condition [0x0000000000000000]
       java.lang.Thread.State: RUNNABLE
    
       Locked ownable synchronizers:
            - None
    
    "Attach Listener" daemon prio=10 tid=0x00000000025ab800 nid=0x480 waiting on condition [0x0000000000000000]
       java.lang.Thread.State: RUNNABLE
    
       Locked ownable synchronizers:
            - None
    
    "Signal Dispatcher" daemon prio=10 tid=0x00000000025a8800 nid=0xebc runnable [0x0000000000000000]
       java.lang.Thread.State: RUNNABLE
    
       Locked ownable synchronizers:
            - None
    
    "Finalizer" daemon prio=8 tid=0x0000000002592000 nid=0x1dd0 in Object.wait() [0x0000000006d2f000]
       java.lang.Thread.State: WAITING (on object monitor)
            at java.lang.Object.wait(Native Method)
            - waiting on <0x00000007c0961300> (a java.lang.ref.ReferenceQueue$Lock)
            at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)
            - locked <0x00000007c0961300> (a java.lang.ref.ReferenceQueue$Lock)
            at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)
            at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)
    
       Locked ownable synchronizers:
            - None
    
    "Reference Handler" daemon prio=10 tid=0x000000000258e800 nid=0x1560 in Object.wait() [0x0000000006c2f000]
       java.lang.Thread.State: WAITING (on object monitor)
            at java.lang.Object.wait(Native Method)
            - waiting on <0x00000007c09611d8> (a java.lang.ref.Reference$Lock)
            at java.lang.Object.wait(Object.java:485)
            at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)
            - locked <0x00000007c09611d8> (a java.lang.ref.Reference$Lock)
    
       Locked ownable synchronizers:
            - None
    
    "VM Thread" prio=10 tid=0x0000000002588000 nid=0x1d38 runnable
    
    "GC task thread#0 (ParallelGC)" prio=6 tid=0x00000000024e1800 nid=0x1e40 runnable
    
    "GC task thread#1 (ParallelGC)" prio=6 tid=0x00000000024e3000 nid=0x1854 runnable
    
    "GC task thread#2 (ParallelGC)" prio=6 tid=0x00000000024e4800 nid=0x1e00 runnable
    
    "GC task thread#3 (ParallelGC)" prio=6 tid=0x00000000024e6800 nid=0x970 runnable
    
    "VM Periodic Task Thread" prio=10 tid=0x00000000025c2000 nid=0xf00 waiting on condition
    
    JNI global references: 882
    
    
    Found one Java-level deadlock:
    =============================
    "b":
      waiting to lock monitor 0x0000000002598548 (object 0x00000007c099b648, a java.lang.String),
      which is held by "a"
    "a":
      waiting to lock monitor 0x0000000002595de8 (object 0x00000007c099b668, a java.lang.String),
      which is held by "b"
    
    Java stack information for the threads listed above:
    ===================================================
    "b":
            at mytask.DeadThread.run(Task.java:40)
            - waiting to lock <0x00000007c099b648> (a java.lang.String)
            - locked <0x00000007c099b668> (a java.lang.String)
            at java.lang.Thread.run(Thread.java:662)
    "a":
            at mytask.DeadThread.run(Task.java:27)
            - waiting to lock <0x00000007c099b668> (a java.lang.String)
            - locked <0x00000007c099b648> (a java.lang.String)
            at java.lang.Thread.run(Thread.java:662)
    
    Found 1 deadlock.

    死锁的一个经典场景为哲学家就餐问题。 产生死锁的原因主要是:

    (1) 因为系统资源不足。
    (2) 进程运行推进的顺序不合适。
    (3) 资源分配不当等。
    如果系统资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很低,否则就会因争夺有限的资源而陷入死锁。其次,进程运行推进顺序与速度不同,也可能产生死锁。
    产生死锁的四个必要条件:
    (1) 互斥条件:一个资源每次只能被一个进程使用。
    (2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
    (3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
    (4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
    这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。

    死锁的解除与预防:
    理解了死锁的原因,尤其是产生死锁的四个必要条件,就可以最大可能地避免、预防和
    解除死锁。所以,在系统设计、进程调度等方面注意如何不让这四个必要条件成立,如何确
    定资源的合理分配算法,避免进程永久占据系统资源。此外,也要防止进程在处于等待状态
    的情况下占用资源。因此,对资源的分配要给予合理的规划。

  • 相关阅读:
    用户交互程序
    使用 fetch 封装网络请求,返回promise 对象
    我收藏的脚手架
    DOM API简析
    encodeURI、encodeURIComponent、decodeURI、decodeURIComponent的区别
    Flex 布局
    react 基础
    javaScript 设计模式
    js 之正则表达式
    如何使用RedisTemplate访问Redis数据结构
  • 原文地址:https://www.cnblogs.com/soar-hu/p/6724174.html
Copyright © 2011-2022 走看看