Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么书中的ReentrantLock算法不起作用?_Java_Multithreading_Concurrency - Fatal编程技术网

Java 为什么书中的ReentrantLock算法不起作用?

Java 为什么书中的ReentrantLock算法不起作用?,java,multithreading,concurrency,Java,Multithreading,Concurrency,今天我读了一篇文章,发现了一件我个人很难理解的事情 因此,我找到了java中的ReentrantLock实现(对我来说,是第188页,第8章): 我分析了这段代码,但仍然没有完全理解它 因此,我可以通过以下方式使用java.util.concurrent.locks中的ReentrantLock: lock.lock(); lock.lock(); // Some code here... lock.unlock(); lock.unlock(); 这样就可以了,因为它是可重入锁定的,我可以多

今天我读了一篇文章,发现了一件我个人很难理解的事情

因此,我找到了java中的ReentrantLock实现(对我来说,是第188页,第8章):

我分析了这段代码,但仍然没有完全理解它

因此,我可以通过以下方式使用
java.util.concurrent.locks
中的
ReentrantLock

lock.lock();
lock.lock();
// Some code here...
lock.unlock();
lock.unlock();
这样就可以了,因为它是可重入锁定的,我可以多次获得临界截面

例如,您可以从本书中找到自旋锁实现:

class TASLock implements Lock {
    private AtomicBoolean state = new AtomicBoolean(false);

    @Override
    public void lock() {
        while(state.getAndSet(true));
    }

    @Override
    public void unlock() {
        state.set(false);
    }

    // Other Lock methods...
}
此实现按预期工作

因此,您可以从
simpleentrantlock
中注意到下一件事:

 lock = new SimpleLock();
正如作者告诉我们的:

我们将内部锁字段初始化为(虚构的)SimpleLock类的对象,该类可能不可重入

但实际上,我已经实现了非重入锁(
TASLock
),所以我将进行下一个内联:

lock = new TTASLock();
最后,当我尝试执行下一个代码时,我将出现死锁:

new Thread(() -> {
            lock.lock();
            lock.lock();
            System.out.println("No deadlock found.");
            lock.unlock();
            lock.unlock();
}).start();
这看起来很清楚,因为在
lock
方法中,我们有这样的代码:

 lock.lock();
实际上,我们在没有任何先决条件的情况下,尝试在同一个锁对象上获取两次临界截面

书中是否指出了错误的算法?或者我不明白什么吗?

lock()方法中缺少lock.unlock()。算法是正确的,这是一个简单的疏忽。
如书中所述:

因为这两个字段是原子操作的,所以我们需要一个内部短期锁

为了回答评论中的问题,下面是lock()的更正版本:


现在你的问题是什么?@RavindraRanwala我的问题是:书中指出的算法是错误的吗?或者我不明白什么吗?因为在这本书中,互斥的这种算法被称为“可重入的”,正如我所看到的,实际上不是。所以,我有点困惑,这就是为什么我要问这个问题。为什么你说它不可重入或不工作?你有什么证据?@Ravindranwala reentrant lock没有死锁,如果你在同一个互斥锁上多次获得它。所以,请检查我的例子。无论如何,你可以自己测试它,因为我共享了代码(从书中)。你能告诉我这个解锁在代码中遗漏了什么吗?我把它添加到了anwserSo中,它看起来像书中的一个打字错误。
 lock.lock();
    public void lock() {
    long me = Thread.currentThread().getId();
    lock.lock();
    try{
    if (owner == me) {
        holdCount++;
        return;
    }

    while (holdCount != 0) {
        try {
            condition.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    owner = me;
    holdCount = 1L;
    } finally {        
        lock.unlock();  // this call is missing
    }
}