避免死锁:中断响应与等待限时

调用重入锁的lock()方法去申请锁,如果锁被占用了,那么线程就会一直等待锁,有时候这样的情况并不好,如果等待锁的时间太长了,应该去干点别的事情,回来再申请锁。也就是说,一个线程等待锁时,可以中断等待,继续干线程自己的事情。那么如果让一个线程不会一直等待锁的申请,转而去响应中断呢?就要用到lockInterruptibly()方法,是一个可以对中断进行响应的锁申请动作。

具体来看一段代码:

代码要做的就是实例化两个线程,线程1先申请lock1锁,睡眠一秒后再申请lock2锁;线程2则相反,先申请lock2锁,完了睡眠一秒再申请lock1锁。当两个线程都执行后,会造成死锁,线程1占有lock1锁同时申请lock2锁,线程2占有lock2锁同时申请lock1锁, 此时两个线程产生死锁,不过在主线程中第70行我们对线程2做中断操作,线程2会放弃对锁lock1的申请,同时释放锁lock2,所以线程1会得到锁lock2,并成功退出。输出结果如下“

由输出结果可以看出,线程2没有输出执行完成的语句,也就是说线程2并没有获得锁lock1,在线程2响应中断后,放弃了对锁lock1的申请而直接执行下面的语句,也就是输出退出语句。

线程1获得锁lock1后申请锁lock2,虽然产生了死锁,但线程2后来放弃了锁lock1申请,并释放了锁lock2,所以线程1可以得到锁lock2,输出执行完成的语句。

中断响应是锁申请等待过程中可以放弃等待转去处理中断,等待限时是线程申请锁时给定一个等待时间,如果等待时间过后线程还没能拿到锁,那么线程就停止等待。像短作业优先调度算法中有可能出现的饥饿现象,给定锁一个等待限时是很有用的。想要在申请锁时给定一个限时,就要用到重入锁中的方法tryLock(long time,TimeUnit unit),两个参数,一个表示时长,一个表示时间单位,看下面这段代码:

对于上面的代码,tryLock()方法中等待时长为5,时间单位是秒,也就是申请锁等待时间最长为5秒。线程1获得锁lock后会输出成功语句然后睡眠6秒,此时线程2申请锁lock2就会失败,在等待5秒后因为还得不到锁而输出失败语句:

tryLock()方法调用可以不带任何的参数,这样表示申请锁的动作不会引起等待,线程调用零参数的tryLock()方法,如果得到锁后会返回true,得不到锁就会返回false,并且不会等待锁。我们来看下这段代码:

上面代码做的事情和前面一样,就是构造死锁的情况,在线程t1获得lock1锁后,睡眠一秒再去申请lock2锁,线程t2相反。不过两个线程的锁申请都是不等待的,所以只要时间足够长,两个线程都能拿到资源的,输出结果:

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值