首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

如何处理死锁-JCIPC10读书笔记

2012-11-05 
如何避免死锁--JCIPC10读书笔记[本文是我对Java Concurrency In Practice C10的归纳和总结. ?转载请注明作

如何避免死锁--JCIPC10读书笔记

[本文是我对Java Concurrency In Practice C10的归纳和总结. ?转载请注明作者和出处, ?如有谬误, 欢迎在评论中指正. ]

如果多个线程以不同的顺序持有多个锁, 可能发生死锁:

?

public class AccountTrans {// 额外的锁private static final Object tieLock = new Object();public void transferMoney(final Account fromAcct, final Account toAcct, final DollarAmount amount)throws InsufficientFundsException {class Helper {public void transfer() throws InsufficientFundsException {if (fromAcct.getBalance().compareTo(amount) < 0)throw new InsufficientFundsException();else {fromAcct.debit(amount);toAcct.credit(amount);}}}// 计算fromAcct和toAcct的hashCode值int fromHash = System.identityHashCode(fromAcct);int toHash = System.identityHashCode(toAcct);// 根据hashCode值确定获取锁的顺序if (fromHash < toHash) {synchronized (fromAcct) {synchronized (toAcct) {new Helper().transfer();}}} else if (fromHash > toHash) {synchronized (toAcct) {synchronized (fromAcct) {new Helper().transfer();}}} else {// 当hashCode值相同时, 无法确定fromAcct和头Acct锁的获取顺序, 因此增加额外的锁synchronized (tieLock) {synchronized (fromAcct) {synchronized (toAcct) {new Helper().transfer();}}}}}}
?

open call

所谓open call是指在未持有锁时调用外部方法. 持有锁的时候调用外部方法, 如果被调用的方法需要获取其他的锁, 可能带来死锁的风险. 如果被调用的方法发生阻塞, 当前线程将长时间持有锁, 其他等待获取该锁的线程就会被阻塞.

因此我们应该尽量在未持有锁的时候进行方法的调用.

?

资源死锁

比如线程A持有数据库D1的连接, 并等待获取数据库D2的连接. 而线程B持有数据库D2的连接, 并等待获取数据库D1的连接. 此时就发生了死锁.

资源死锁的另一种形式是线程饥饿死锁, 参见第八章.

?

避免死锁

1. 尽量不要同时持有多个锁.

2. 如果必须同时持有多个锁, 那么保证以一致的顺序获取锁.

3. 尽量在未持有锁的情况下进行方法的调用(open call).

热点排行