一文搞懂多线程中的死锁问题和解决思路

一、.死锁定义

死锁是指两个或两个以上的进程在执⾏过程中,由于竞争资源或者由于彼此通信⽽造成的⼀种阻塞的现象,若⽆外⼒作⽤,它们都将⽆法推进下去。

二、死锁产⽣的原因

形成死锁主要由以下 4 个因素造成的:
以下这四个条件缺一不可

① 互斥条件

⼀个资源只能被⼀个线程占有,当这个资源被占⽤之后其他线程就只能等待。

② 不可被剥夺条件

当⼀个线程不主动释放资源时,此资源⼀直被拥有线程占有,其它线程就得不到此资源。

③ 请求并持有条件

线程已经拥有了⼀个资源之后,有尝试请求新的资源。

④ 环路等待条件

产⽣死锁⼀定是发⽣了线程资源环形链。

三、解决死锁的思路

利用死锁的产生条件解决死锁问题

1.条件1是改变不了的
2.条件2也是改变不了的
3.条件3可以人认为控制,可以打破。
4.条件4可以打破也可以修改。
环路等待条件的破坏:使用顺序锁解决死锁问题

在这里插入图片描述

四、死锁产生示例

package Thread;
/**
 * 死锁示例
 */
import java.util.concurrent.TimeUnit;
public class ThreadUnDeadLock1 {
    public static void main(String[] args) {
        Object lockA = new Object();
        Object lockB = new Object();
        Thread t1 = new Thread(()->{
            // 1.占有一把锁(锁A)
            synchronized(lockA){
                System.out.println("线程1获得锁A");
                //休眠1S让线程2获取锁B
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //获取线程2的锁B
                synchronized(lockB){
                    System.out.println("线程1,获得锁B");
                }
            }
        });
        t1.start();
        Thread t2 = new Thread(()->{
            //占有一把锁B
            synchronized(lockB){
                System.out.println("线程2获取锁B");
                // 休眠1s(保证线程1能有充足的时间得到锁A)
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized(lockA){
                    System.out.println("线程2获取到了锁B!");
                }
            }
        });
        t2.start();
    }
}

五、解决死锁示例

package Thread;
/**
 * 使用顺序锁来解决循环死锁问题
 */

import java.util.concurrent.TimeUnit;

public class ThreadUnDeadLock2 {
    public static void main(String[] args) {
        Object lockA = new Object();
        Object lockB = new Object();
        Thread t1 = new Thread(()->{
            synchronized(lockA){
                System.out.println("线程1得到了锁A");
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                }
                synchronized(lockB){
                    System.out.println("线程1得到了锁B");
                    //业务代码
                    System.out.println("线程1释放了锁B");
                }
                System.out.println("线程1释放了锁A");
            }
        },"线程1");
        t1.start();
        Thread t2 = new Thread(()->{
            synchronized(lockA){
                System.out.println("线程2获取了锁A");
                synchronized (lockB){
                    System.out.println("线程2得到了锁B");
                    //业务代码
                    System.out.println("线程2释放了锁B");
                }
                System.out.println("线程2释放了锁A");

            }
        },"线程2");
        t2.start();
    }
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值