java - ReentrantReadWriteLock 丢失——抛出 IllegalMonitorStateException

标签 java locking

当从 finally block 中解锁时,我的程序抛出一个 IllegalMonitorStateException。 Javadoc 说这个异常被抛出“如果当前线程不持有这个锁”。但是,如果程序曾经到达 finally block ,那么它之前一定已经获得了锁。锁之前没有在其他地方解锁过。锁会“迷路”吗?

代码示例:

final ReadWriteLock rwLock = new ReentrantReadWriteLock();

public void doSomething() {
    Lock lock = rwLock.writeLock();
    try {
        doStuff();
    } finally {
        lock.unlock();
    }
}

最佳答案

ReentrantLock 升级到 ReentrantReadWriteLock 时会出现此问题,因为这两个类的语义不同。此代码按预期工作:

final Lock lock = new ReentrantLock();

public void doSomething() {
    lock.lock();
    try {
        doStuff();
    } finally {
        lock.unlock();
    }
}

区别在于,lock.lock() [可选地等待然后] 按预期获取当前线程的锁,但 rwLock.writeLock() 确实只返回 ReentrantReadWriteLock 实例的写锁部分,不会尝试锁定任何东西。至于this example ,代码应该是这样的:

final ReadWriteLock rwLock = new ReentrantReadWriteLock();

public void doSomething() {
    rwLock.writeLock().lock();
    try {
        doStuff();
    } finally {
        rwLock.writeLock().unlock();
    }
}

getter 方法 writeLock()——还有 readLock()——每次都为同一个线程返回同一个锁,所以获得的锁不需要保存在变量中以便稍后解锁,您可以简单地获取“新的”来解锁“旧的”,因为它们必须相同。 (这是因为 Thread.currentThread() 是静态的。)

关于java - ReentrantReadWriteLock 丢失——抛出 IllegalMonitorStateException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17827263/

相关文章:

java - Jooq - 忽略重复项

java - "Chaining"两个 Controller ?

ios - 检测 iOS 设备何时从 sleep 中唤醒

java - 可重入锁可以完全替代同步吗?

postgresql - postgresql插入和选择时如何锁表?

java - 自定义阻塞队列锁定问题

Java IE - 用于 Java 的 Internet Explorer

java - 应为 BEGIN_OBJECT,但经过改造后为 BEGIN_ARRAY

java - 如何使用 for 循环迭代数组列表并每 X 次执行一个操作? java

c# - 锁定语句似乎不起作用