带有锁对象的 java oracle 教程中的 Bow/Bower 示例

Posted

技术标签:

【中文标题】带有锁对象的 java oracle 教程中的 Bow/Bower 示例【英文标题】:Bow/Bower example in java oracle tutorial with lock object 【发布时间】:2019-03-15 00:17:27 【问题描述】:

在 java 文档示例中,lock.unlock() 方法被使用了两次,一次在 impendingBow() 方法和 bow() 方法中。我的问题是,impendingBow() 方法中的 lock.unlock() 方法不应该起作用吗,为什么要在 bow() 方法中再次使用它?下面的代码是来自 java docs 的 sn-p :

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 bowing to"
                + " him.%n",
                this.name, bower.getName());
        
    

【问题讨论】:

方法impendingBow 仅在tryLock() 调用之一失败时调用lock.unlock()(注意if (! (myLock && yourLock)) 检查)。在这种情况下,该方法返回 false。只有在 impendingBow() 调用返回 true 之后,bow 方法才会调用 lock.unlock()。那里没有问题。 只想说这是一个非常奇怪复杂的例子,更令人困惑的是,它演示了锁是如何工作的......恕我直言 【参考方案1】:

不应该在impendingBow() 方法中使用lock.unlock() 方法,为什么要在bow() 方法中再次使用它?

impendingBow 中,当两次锁定尝试都成功时,将无法到达lock.unlock()。该方法返回true,使两个锁都处于锁定状态。请参阅解锁调用之前的条件语句。在这种情况下(两个锁都成功),bow() 必须解锁锁。

【讨论】:

以上是关于带有锁对象的 java oracle 教程中的 Bow/Bower 示例的主要内容,如果未能解决你的问题,请参考以下文章

zbb20170728 oracle 查看被锁对象

Oracle 锁机制探究

请问java中的lock和synchronized区别是啥?

Java多线程-synchronized同步方法

请问java中的lock和synchronized区别是啥?

JAVA中的内锁机制是啥