如何理解Oracle Java教程中用ReentrantLock实现Bow/Bower同步避免死锁的示例?
嘿,这就给你把这段用Lock对象解决Bow/Bower同步死锁的Java代码整理得明明白白,用Markdown格式呈现:
使用Lock对象避免死锁的同步实现
下面是完整的代码实现,核心通过ReentrantLock的tryLock()机制避免死锁:
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import java.util.Random; public class Safelock { static class Friend { private final String name; private final Lock lock = new ReentrantLock(); public Friend(String name) { this.name = name; } public String getName() { return this.name; } public boolean impendingBow(Friend bower) { Boolean myLock = false; Boolean yourLock = false; try { // 尝试获取自己和对方的锁,而非阻塞等待 myLock = lock.tryLock(); yourLock = bower.lock.tryLock(); } finally { // 如果没同时拿到两把锁,释放已获取的锁 if (!(myLock && yourLock)) { if (myLock) { lock.unlock(); } if (yourLock) { bower.lock.unlock(); } } } return myLock && yourLock; } public void bow(Friend bower) { if (impendingBow(bower)) { try { System.out.format("%s: %s has bowed to me!%n", this.name, bower.getName()); bower.bowBack(this); } finally { // 确保锁最终被释放 lock.unlock(); bower.lock.unlock(); } } else { System.out.format("%s: %s started to bow to me, but saw that I was already trying to bow to them.%n", this.name, bower.getName()); } } public void bowBack(Friend bower) { System.out.format("%s: %s has bowed back to me!%n", this.name, bower.getName()); } } static class BowLoop implements Runnable { private Friend bower; private Friend bowee; public BowLoop(Friend bower, Friend bowee) { this.bower = bower; this.bowee = bowee; } public void run() { Random random = new Random(); for (;;) { try { Thread.sleep(random.nextInt(10)); } catch (InterruptedException e) {} bowee.bow(bower); } } } public static void main(String[] args) { final Friend alphonse = new Friend("Alphonse"); final Friend gaston = new Friend("Gaston"); new Thread(new BowLoop(alphonse, gaston)).start(); new Thread(new BowLoop(gaston, alphonse)).start(); } }
核心逻辑说明
- 死锁规避:用
tryLock()替代阻塞式的lock(),如果无法同时获取自己和对方的锁,就主动释放已拿到的锁,避免双方僵持 - 锁安全保障:所有锁的释放操作都放在
finally块中,确保无论代码是否抛出异常,锁都会被正确释放,防止锁泄漏 - 逻辑解耦:把锁获取的逻辑抽离到
impendingBow()方法中,让业务方法bow()的逻辑更清晰
内容的提问来源于stack exchange,提问作者Sidhant Sinha
相关产品推荐
相关产品推荐

