死锁的必要条件和解决方案1

1.2 死锁
所谓死锁是指多个线程因竞争资源而造成的一种僵局(互相等待)
生活中的一个实例,2个人一起吃饭但是只有一双筷子,2人轮流吃(同时拥有2只筷子才能吃)。某一个时候,一个拿了左筷子,一人拿了右筷子,2个人都同时占用一个资源,等待另一个资源,这个时候甲在等待乙吃完并释放它占有的筷子,同理,乙也在等待甲吃完并释放它占有的筷子,这样就陷入了一个死循环,谁也无法继续吃饭。
1.2.1 死锁产生的条件
(1)互斥条件。进程对所分配到的资源进行排他性使用,即在一段时间内,某资源只能被一个进程占用。如果此时还有其他进程请求该资源,则请求进程只能等待,直至占有该资源的进程用毕释放。
(2)请求和保持条件。进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源已被其他进程占有,此时请求进程被阻塞,但对自己以获得的资源保持不放。
(3)不可抢占条件。进程已获得的资源在未使用完之前不能被抢占,只能在进程使用完时由自己释放。
(4)循环等待条件。在发生死锁时,必然存在一个进程—资源的循环链,即进程集合{P0,P1,P2,P3,…,Pn}中的P0正在等待P1占用的资源,P1正在等待P2占用的资源,… … ,Pn正在等待已被P0占用的资源。
死锁的示例:

/**

  • 当DeadLock类的对象flag==1时(td1),先锁定o1,睡眠500毫秒
  • 而td1在睡眠的时候另一个flag==0的对象(td2)线程启动,先锁定o2,睡眠500毫秒
  • td1睡眠结束后需要锁定o2才能继续执行,而此时o2已被td2锁定;
  • td2睡眠结束后需要锁定o1才能继续执行,而此时o1已被td1锁定;
  • td1、td2相互等待,都需要得到对方锁定的资源才能继续执行,从而死锁。
    */
    public class DeadLock implements Runnable {
    public int flag = 1;
    //静态对象是类的所有对象共享的
    private static Object o1 = new Object(), o2 = new Object();
    @Override
    public void run() {
    System.out.println(“flag=” + flag);
    if (flag == 1) {
    synchronized (o1) {
    try {
    Thread.sleep(500);
    } catch (Exception e) {
    e.printStackTrace();
    }
    synchronized (o2) {
    System.out.println(“1”);
    }
    }
    }
    if (flag == 0) {
    synchronized (o2) {
    try {
    Thread.sleep(500);
    } catch (Exception e) {
    e.printStackTrace();
    }
    synchronized (o1) {
    System.out.println(“0”);
    }
    }
    }
    }
    public static void main(String[] args) {
    DeadLock td1 = new DeadLock();
    DeadLock td2 = new DeadLock();
    td1.flag = 1;
    td2.flag = 0;
    //td1,td2都处于可执行状态,但JVM线程调度先执行哪个线程是不确定的。
    //td2的run()可能在td1的run()之前运行
    new Thread(td1).start();
    new Thread(td2).start();
    }
    }

1.2.2 处理死锁的几个常见的方法
预防死锁:
破坏死锁的四个必要条件中的一个或多个来预防死锁。
避免死锁:
和预防死锁的区别就是,在资源动态分配过程中,用某种方式防止系统进入不安全的状态。
1、加锁顺序(线程按照一定的顺序加锁)因为当多个线程需要相同的一些锁,但是按照不同的顺序加锁,死锁就很容易发生。
2、加锁时限(线程尝试获取锁的时候加上一定的时限,超过时限则放弃对该锁的请求,并释放自己占有的锁)
检测死锁:
运行时出现死锁,能及时发现死锁,把程序解脱出来
解除死锁:
发生死锁后,解脱进程,通常撤销进程,回收资源,再分配给正处于阻塞状态的进程。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值