10_活跃性问题

活跃性问题

一、死锁

1.1 死锁条件

  • 互斥:资源是互斥的,只能被一个线程持有
  • 占用且等待:线程占有一些资源后,在等待其他资源,等待过程中不会释放自己已占用的资源
  • 不可剥夺:不可以强行剥夺已被线程占有的资源
  • 循环等待:占用资源的线程在循环等待其他占用资源的线程释放资源

1.2 死锁避免

避免死锁的办法,就是破坏死锁的四个条件:

  • 互斥:开放调用,减少锁范围,避免对方法加锁,避免获取多个锁
  • 占用且等待:一次性获取全部资源,避免锁等待
  • 不可剥夺:线程自己释放资源即可,比如超时释放锁,随机等待获取锁等
  • 循环等待:对资源进行排序,有序申请占用资源

1.3 死锁诊断

  • 代码分析
    • 找出可能获取多个锁的代码区域
    • 全局分析,确保获取它们获取锁的顺序是一致的,避免循环等待
  • JVM 线程转储信息
    • JVM 线程转储信息可以打印出死锁相关信息

二、饥饿

  • 饥饿:线程由于无法访问它所需资源而不能继续执行时,发生饥饿
  • 出现这种现象的情况有:
    • 优先级使用不当
    • 长时间持有锁不释放
  • 解决饥饿的方案有:
    • 避免使用优先级
    • 使用公平锁,线程按先来后到执行,有序执行
    • 超时释放锁,避免长时间持有锁

三、活锁

  • 活锁:线程之间相互谦让,同时加锁资源又同时释放资源,导致没有线程可以执行
  • 出现这种现象的情况有:
    • 冲突后同时等待和重发,比如网络数据包,两台机器同时发包导致冲突,然后又等待同样的时间,再继续发包,又会冲突
    • 过度的错误恢复,将不可修复错误当作可修复错误重复执行。比如,事务执行失败回滚,然后又重新执行,又失败回滚,一直循环
  • 避免活锁的方案有:
    • 随机等待时间,避免活锁的同时占用和同时释放资源,随机等待可以降低冲突
作者

jiaduo

发布于

2022-05-15

更新于

2023-04-03

许可协议