什么是死锁,如何避免死锁?Java死锁详解

什么是死锁

死锁是指多个进程因竞争资源而引起的一种僵局,如果没有外力作用,所有进程都不会向前推进。
举例:假如有线程Thread1和Thread2,两个都要访问共享资源AB,Thread1和Thread2一个先访问A再访问B,另一个先访问B再访问A。但在他们线程未执行完时,都不会释放AB资源,那么就形成了一种僵局,Thread1在等待Thead2施放B资源,Thread2在等待Thread1释放A资源,两个进程就形成了一种僵局,下面以Java代码实现为例说明:


public class DeadThread {
   

    private Thread thread1;


    public DeadThread(Object object1,Object object2){
   

        thread1 = new Thread(() -> {
   

                synchronized (object1){
   
                    System.out.println("获取到o1"+Thread.currentThread().getName());
                    try {
   
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
   
                        e.printStackTrace();
                    }
                        synchronized (object2){
   
                System.out.println("获取到o2"+Thread.currentThread().getName());
            }
                }
        


    });
        thread1.start();
    }

    public static void main(String[] args) {
   
        Object object1=new Object();
        Object object2=new Object();
        DeadThread deadThread=new DeadThread(object1,object2);
        DeadThread deadThread1=new DeadThread(object2,object1);


    }

}

其中Object1和Object2就是上述的资源AB。

死锁产生的必要条件

  1. 互斥条件:资源互斥访问。一个资源每次只能被一个进程使用,即在一段时间内某 资源仅为一个进程所占有。此时若有其他进程请求该资源,则请求进程只能等待。
  2. 请求保持:进程已经拥有了资源,又请求资源。进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源 已被其他进程占有,此时请求进程被阻塞,但对自己已获得的资源保持不放。
  3. 不可剥夺:进程拥有的资源不会被剥夺,只能自己主动释放。进程所获得的资源在未使用完毕之前,不能被其他进程强行夺走,即只能 由获得该资源的进程自己来释放(只能是主动释放)。
  4. 循环等待: 进程之间形成了一个循环等待资源的环。若干进程间形成首尾相接循环等待资源的关系。
    死锁产生的原因

死锁产生的原因

进程推进顺序非法。
进程竞争资源。

Java中怎么监测死锁

还是以上述程序为例:可以看到这两个线程都处于blocked状态
用idea自带的debug功能
在这里插入图片描述
在这里插入图片描述
或者用jconsole工具来查看(未使用过)

操作系统中如何避免或打破死锁

破坏死锁的必要条件,互斥条件是不可变的,只能想办法打破后三个条件。
比如破坏请求保持条件,进程必须一次性申请所需的全部资源。还有著名的银行家算法。等等,这里不作详细介绍

Java中如何避免或打破死锁

根据Java核心技术卷I中的说法,**在Java语言中没有任何东西可以避免或打破这种死锁现象,必须仔细设计程序,以确保不会出现死锁。**言下之意即,程序员在设计线程时,必须想办法尽量避免死锁现象。

后来,查阅资料发现jdk1.5后新增了一个类可用于侦察死锁,见下文Reentranlock处:

程序输出

在这里插入代码片获取到锁2135218919Thread-1
获取到锁131519948Thread-0
---[J@6d311334
tsun.misc.Unsafe.park(Native Method)
tjava.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
tjava.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
tjava.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:870)
tjava.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1199)
tjava.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:209)
tjava.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:285)
tDeadThread1.lambda$new$0(DeadThread1.java:27)
tDeadThread1$$Lambda$1/1096979270.run(Unknown Source)
tjava.lang.Thread.run(Thread.java:748)
tsun.misc.Unsafe.park(Native Method)
tjava.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
tjava.util.concurrent.locks.AbstractQueuedSynchronizer.
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值