安全性和活跃度通常相互牵制。滥用锁可能引起锁顺序死锁或资源死锁。
java应用程序不能从死锁中恢复。
1、死锁
数据库系统设计针对了监测死锁,以及从死锁中恢复。在事务中选择一个牺牲者,使其他事务能够继续进行。
如果所有线程以通用的固定秩序获得锁,程序就不会出现锁顺序死锁的问题了。
在持有锁的时候调用外部方法是在挑战活跃度问题。外部方法可能会获得其他锁(产生死锁的风险),或者遭遇严重超时的阻塞。当你持有锁的时候会延迟其他试图获得该锁的线程。
在持有锁的时候调用一个外部方法很难进行分析,因此是危险的。
当调用的方法不需要持有锁时,这被称为开放调用。
在程序中尽量使用开放调用。依赖于开放调用的程序,相比于那些在持有锁的时候还调用外部方法的程序,更容易进行死锁自由度的分析。
2、避免和诊断死锁
尝试定时锁:如果获取锁的请求超时,你可以释放这个锁,并后退,等待一会儿再尝试,这很可能消除了死锁发生的条件,并且允许程序恢复。
通过线程转储分析死锁。
3、其他活跃度危险
饥饿,丢失信号和活锁。
抵制使用线程优先级的诱惑,因为这会增加平台依赖性,并且可能引起活跃度问题。大多数并发应用程序可以对所有线程使用相同的优先级。
活锁是线程中活跃度失败的另一种形式,尽管没有被阻塞,线程却仍然不能继续,因为它不断重试相同的操作,却总是失败。(解决方案:对重试机制引入一些随机性)