Java 多线程之程序死锁及如何诊断

程序死锁的原因

  1. 交叉锁原因可导致程序出现死锁
    线程A持有R1的锁等待线程B的R2的锁,线程A持有R1的锁,线程B持有R2的锁,大家互相等待,死锁;

  2. 内存不足
    当并发系统请求可用内存,如果此时系统内存不足,则可能会出现死锁情况,两个线程T1和T2,执行某个任务,其中T1已经获取10MB内存,T2获取了20MB内存,如果每个线程的执行单元都需要30MB的内存,但是剩余的内存刚好为20MB,那么两个线程有可能在等待彼此能释放内存资源。

  3. 一问一答的数据交换
    服务端开启某个端口,等待客户端访问,客户端发送请求立即等待接收,由于服务端某种原因错过丢失了请求,陷入了互相等待过程。

  4. 数据库锁
    无论是数据表级别,还是行级别的锁,比如某个线程执行for update 退出的事物 其他访问数据库时都将陷入死锁

  5. 文件锁
    同理 某线程获得文件所意外所意外退出,其他读取文件线程也会进入死锁,直到释放文件句柄资源

  6. 死循环引起的死锁
    死循环获得锁

程序死锁举例

本节中,我们将举例由于交叉锁引起死锁的情况,交叉锁不仅是自己代码有可能有问题,还有一些开源框架api 不熟悉导致死锁情况出现,前者比后者排查简单得多,所以开发过程中熟悉api很有必要。

package thread.deadlock;

public class Demo {
    private final Object read_lock=new Object();
    private final Object write_lock=new Object();
    public void read(){
        synchronized (read_lock){
            System.out.println("I will read,and this read_lock will belong me ");
            synchronized (write_lock){
                System.out.println("I will write,and those locks are all mine hhhhha");
                System.out.println(Thread.currentThread().getName()+"heiehiehie");
            }
            System.out.println("I lost wrote_lock  yingying ");
        }
        System.out.println("i lost all");
    }
    public void write(){
        synchronized (write_lock){
            System.out.println("I will write,and those locks are all mine hhhhha");
            synchronized (read_lock){

                System.out.println(Thread.currentThread().getName()+"是我");
            }
            System.out.println("I lost wrote_lock  yingying ");
        }
        System.out.println("i lost all");
    }

    public static void main(String[] args) {
        final Demo demo = new Demo();
        new Thread(()->{
           while (true){
               demo.read();
           }
        },"read Thread\t").start();
        new Thread(()->{
            while (true){
                demo.write();
            }
        },"write Thread \t").start();

    }
}

运行结果


I will read,and this read_lock will belong me 
I will write,and those locks are all mine hhhhha
read Thread	heiehiehie
I lost wrote_lock  yingying 
i lost all
I will read,and this read_lock will belong me 
I will write,and those locks are all mine hhhhha
read Thread	heiehiehie
I lost wrote_lock  yingying 
i lost all
I will read,and this read_lock will belong me 
I will write,and those locks are all mine hhhhha
read Thread	heiehiehie
I lost wrote_lock  yingying 
i lost all
I will read,and this read_lock will belong me 
I will write,and those locks are all mine hhhhha
read Thread	heiehiehie
I lost wrote_lock  yingying 
i lost all
I will read,and this read_lock will belong me 
I will write,and those locks are all mine hhhhha
read Thread	heiehiehie
I lost wrote_lock  yingying 
i lost all
I will read,and this read_lock will belong me 
I will write,and those locks are all mine hhhhha
read Thread	heiehiehie
I lost wrote_lock  yingying 
i lost all
I will read,and this read_lock will belong me 
I will write,and those locks are all mine hhhhha
read Thread	heiehiehie
I lost wrote_lock  yingying 
i lost all
I will read,and this read_lock will belong me 
I will write,and those locks are all mine hhhhha
read Thread	heiehiehie
I lost wrote_lock  yingying 
i lost all
I will read,and this read_lock will belong me 
I will write,and those locks are all mine hhhhha
read Thread	heiehiehie
I lost wrote_lock  yingying 
i lost all
I will read,and this read_lock will belong me 
I will write,and those locks are all mine hhhhha
read Thread	heiehiehie
I lost wrote_lock  yingying 
i lost all
I will read,and this read_lock will belong me 
I will write,and those locks are all mine hhhhha
read Thread	heiehiehie
I lost wrote_lock  yingying 
i lost all
I will read,and this read_lock will belong me 
I will write,and those locks are all mine hhhhha
read Thread	heiehiehie
I lost wrote_lock  yingying 
i lost all
I will read,and this read_lock will belong me 
I will write,and those locks are all mine hhhhha

结果明显不过,程序直接死锁 不在运行,

那么我们怎么诊断他呢 这里笔者使用的是jconsole 打开终端
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
按步骤操作即可 这时候我们可以看到线程锁持有者是交互的
好了今天就先到这里了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值