[Java并发编程实战] 第10章 避免活跃性危险

死锁
  • 锁的获取顺序要一致;如果锁的顺序未知,可以使用“加时赛”锁,在获得两个锁之前,先要获得这个“加时赛”锁,从而保证每次只有一个线程以未知的顺序获得这两个锁

  • 协作对象之间产生死锁:如果在持有锁时调用某个外部方法,将出现活跃性问题。在这个外部方法中可能会获取其它锁(这可能会产生死锁),或者阻塞时间过长,导致其它线程无法及时获得当前被持有的锁

  • 开放调用:调用某个方法时,不需要持有锁

  • 资源死锁:当多个线程在相同的资源集合上等待时,也会发生死锁(两个线程需要同样两个资源,一个线程持有一个,等待另一个)

    • 线程饥饿死锁:如,一个任务提交另一个任务,并等待被提交任务在单线程的Executor中执行完成;所以有界资源池/线程池与相互依赖的任务不能一起使用
死锁的避免与诊断
  • 定时锁:

    • 显式使用Lock类中的定时tryLock功能,等待超时后会返回失败信息;

    • 只有在同时获取两个锁时才有效,如果在嵌套的方法调用中请求多个锁,即使知道已经持有了外层锁、内层锁请求超时,也无法释放外层锁

  • 通过线程转储信息分析死锁

  • 内置锁与获得他们所在的线程栈帧是相关联的,而显式的Lock只与获得它的线程相关联

其他活跃性危险
  • 饥饿:线程优先级使用不当,或持有锁时执行一些无法结束的结构(无限循环)

  • 糟糕的响应性:CPU密集型的后台任务会与事件线程共同竞争CPU的时钟周期;不良的锁管理,导致某个线程长时间占有一个锁

  • 活锁:线程不断执行相同的操作,而且总会失败;解决方法可以是,在重试机制中引入随机性

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值