如何实现一个程序快速发生死锁

Posted cleaver

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何实现一个程序快速发生死锁相关的知识,希望对你有一定的参考价值。

遇到一个问题,如何快速发生死锁,特意总结一下。
1、死锁的定义
死锁的定义:死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们将无法推进下去,此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程成为死锁进程。
2、死锁产生条件
互斥条件:指进程对所分配到的资源进行排它性使用,即在一段时间内某资源只由一个进程占用。如果此时还有其它进程请求资源,则请求者只能等待,直至占有资源的进程用毕释放。
请求和保持条件:指进程已经保持至少一个资源,但又提出了新的资源请求,而该资源已被其它进程占有,此时请求进程阻塞,但又对自己已获得的其它资源保持不放。
不剥夺条件:指进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放。
环路等待条件:指在发生死锁时,必然存在一个进程——资源的环形链,即进程集合{P0,P1,P2,···,Pn}中的P0正在等待一个P1占用的资源;P1正在等待P2占用的资源,……,Pn正在等待已被P0占用的资源。
3、死锁的例子:
public class DeadLockDemo {
    public static void main(String[] args) {
        final Object o1 = new Object();
        final Object o2 = new Object();
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (o1){
                    //获取o1的锁
                    try{
                        Thread.sleep(1000);
                    }catch (InterruptedException e){
                        e.printStackTrace();
                    }
                    synchronized (o2){
                        //尝试获取02的锁
                    }
                }
            }
        });

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (o2){
                    //获取o2的锁
                    try{
                        Thread.sleep(1000);
                    }catch (InterruptedException e){
                        e.printStackTrace();
                    }
                    synchronized (o1){
                        //尝试获取01的锁
                    }
                }
            }
        });

        //启动两个线程
        t1.start();
        t2.start();
    }
}

4、死锁分析:
Linux用jps命令找出运行的进程pid:(例子运行的程序名称为DeadLockDemo,即pid 为9345)
技术分享图片

然后采用jstack (jstack pid)命令显示当前jvm的dump信息:

技术分享图片

信息最后我们可以清晰看到(发生了死锁,和对象地址):

技术分享图片
 
详细信息为:
Found one Java-level deadlock:
=============================
"Thread-1":
  waiting to lock monitor 0x00007f6f50004e28 (object 0x000000058015fa18, a java.lang.Object),
  which is held by "Thread-0"
"Thread-0":
  waiting to lock monitor 0x00007f6f500062c8 (object 0x000000058015fa28, a java.lang.Object),
  which is held by "Thread-1"

Java stack information for the threads listed above:
===================================================
"Thread-1":
    at DeadLockDemo$2.run(DeadLockDemo.java:35)
    - waiting to lock <0x000000058015fa18> (a java.lang.Object)
    - locked <0x000000058015fa28> (a java.lang.Object)
    at java.lang.Thread.run(Thread.java:745)
"Thread-0":
    at DeadLockDemo$1.run(DeadLockDemo.java:18)
    - waiting to lock <0x000000058015fa28> (a java.lang.Object)
    - locked <0x000000058015fa18> (a java.lang.Object)
    at java.lang.Thread.run(Thread.java:745)

Found 1 deadlock.
 
 
 
技术分享图片


以上是关于如何实现一个程序快速发生死锁的主要内容,如果未能解决你的问题,请参考以下文章

Java并发编程实战 04死锁了怎么办?

使用多线程代码在一张表上发生 MySQL 死锁

并发编程--锁--如何使用命令行和代码定位死锁

JVM如何查看线程死锁

代码片段如何使用CSS来快速定义多彩光标

什么是死锁?