协作对象间的死锁问题
协作对象之间可能存在请求多个锁的情况,虽然每个对象只会请求一个锁,但是由它们协作完成的整体逻辑需要的锁,是所有协作对象依赖锁的集合,这相比上一节讲的 LeftRightDeadLock
和 transferMoney
直接请求多个锁来说,就没有那么明显了。
协作对象请求锁的动作,并不一定在同一个方法中,所以更隐蔽,如果没有前瞻意识,编码过程中很容易忽略这一点、进而引发死锁。
也就是说,某个线程在持有 A
锁期间,如果它调用了其他对象的方法,而恰好这个外部方法执行时又依赖其他某个 B
锁,此时该方法因无法获取 B
锁而阻塞,导致其他线程无法获取 A
锁,死锁就这样悄然发生了。
《 Java 并发编程实践》中出租车调度的例子,实现的就是这种场景。它涉及到外部方法调用,虽然没有显式地请求锁,因当前方法和外部调用方法都需要单独请求其他锁,整个操作本质上需要顺次获取两个锁,这样就跟