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 打开终端
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
按步骤操作即可 这时候我们可以看到线程锁持有者是交互的
好了今天就先到这里了

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值