java - ReentrantReadWriteLock 即使其状态为 Unlocked 也无法获得锁定

标签 java multithreading reentrantlock

我正在尝试使用以下代码锁定线程:

Lock lock = readLock ? getLock(key).readLock() : getLock(key).writeLock();
try {
    boolean locked = lock.tryLock(DEFAULT_TRY_TIME, DEFAULT_TRY_TIME_UNIT); //line 3
    // If false, lock is not acquired
    if (!locked) {
        throw new TryLockTimeoutException(
                key + ": Failed to acquire " + lock + " within " + DEFAULT_TRY_TIME_STRING);
    }
}

第 3 行在 30 分钟后返回 false,因此 TryLockTimeoutException 被抛出错误如下:

com.concurrent.TryLockTimeoutException: keyIp : Failed to acquire java.util.concurrent.locks.ReentrantReadWriteLock$WriteLock@74be2cee[Unlocked] within 30MINUTES
    at com.concurrent.NeAccessLockMap.acquireReadOrWriteLock(NeAccessLockMap.java:72)

请注意,锁定状态显示为“Unlocked in error”。

我不明白为什么会这样?为什么即使锁是空闲的,线程也无法获得锁。

最佳答案

在您的示例中,您尝试获取写锁,但读锁已被锁定,这会阻止您获取写锁。

因为您可以获取一个或多个读锁,或者获取一个写锁,所以当有读锁被获取时,写锁被标记为Unlocked

试试下面的代码:

ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
new Thread() {
    @Override
    public void run() {
        readWriteLock.readLock().lock();
        try {
            // block the read lock
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}.start();
if (!readWriteLock.writeLock().tryLock(1, TimeUnit.SECONDS)) {
    System.out.println(readWriteLock);
    System.out.println(readWriteLock.readLock());
    System.out.println(readWriteLock.writeLock());
}

输出如下:

java.util.concurrent.locks.ReentrantReadWriteLock@31221be2[Write locks = 0, Read locks = 1]
java.util.concurrent.locks.ReentrantReadWriteLock$ReadLock@377dca04[Read locks = 1]
java.util.concurrent.locks.ReentrantReadWriteLock$WriteLock@728938a9[Unlocked]

关于java - ReentrantReadWriteLock 即使其状态为 Unlocked 也无法获得锁定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37939572/

相关文章:

java - Eclipse 说 Java 类无法解析导入的 scala 类型

java - 在 JavaFX 中,observableArrayList 线程安全吗?

c++ - 多个动态链接库(DLL)是否可以从静态库(LIB)共享线程本地存储

Java - 如何修改信号量实现以使其公平

java - 如何正确确定锁的范围

java - 更改 actionBar 下拉菜单背景颜色

java - 输入对话框验证

java - 有没有面向对象的方式在java中使用H2数据库?

python - 多线程无锁将item追加到同一个列表中是否正确?

java - ReentrantLock 不起作用