gpt4 book ai didi

Java Condition 在await() 返回后无法重新获取与其关联的锁(ReentrantLock)

转载 作者:行者123 更新时间:2023-12-01 14:18:53 25 4
gpt4 key购买 nike

import java.util.LinkedList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

class Foo {
private ReentrantLock _lock;
private Condition _cond;
private Thread _thr;
private LinkedList<String> _msgQueue;

public Foo() {
_lock = new ReentrantLock();
_cond = _lock.newCondition();
_msgQueue = new LinkedList<String>();
startThread();
}

public void putMsg(String msg) throws Exception {
_lock.lock();
_msgQueue.addLast(msg);
_cond.signal();
System.out.println(Thread.currentThread().getId() + ": Signal write thread.");
_lock.unlock();
System.out.println(Thread.currentThread().getId() + ": Unlocked.");
}

private void startThread() {
_thr = new Thread() {
public void run() {
_lock.lock();
while(true) {
try {
while (!_msgQueue.isEmpty()) {
String msg = _msgQueue.getFirst();
System.out.println(msg);
_msgQueue.removeFirst();
}

System.out.println(Thread.currentThread().getId() + ": getHoldCount:" + _lock.getHoldCount());
System.out.println((Thread.currentThread().getId() + ": isLocked:" + _lock.isLocked()));
System.out.println(Thread.currentThread().getId() + ": isHeldByCurrentThread:" + _lock.isHeldByCurrentThread());
System.out.println(Thread.currentThread().getId() + ": Awaiting...");

_cond.await();

System.out.println(Thread.currentThread().getId() + ": Write thread awaken");

} catch (Exception e) {
e.printStackTrace();
break;
} finally {
try {
_lock.unlock();
} catch (Exception e) {
}
}
}
System.out.println("Write thread exit.");
}
};

_thr.start();
}
}

public class LockTest {
public static void main(String[] args) throws Exception {
Foo foo = new Foo();
foo.putMsg("Msg 1");
foo.putMsg("Msg 2");
Thread.sleep(1000);
foo.putMsg("Msg 3");
}
}
The code output after one running:1: Signal write thread.1: Unlocked.1: Signal write thread.1: Unlocked.Msg 1Msg 28: getHoldCount:18: isLocked:true8: isHeldByCurrentThread:true8: Awaiting...1: Signal write thread.1: Unlocked.8: Write thread awakenMsg 38: getHoldCount:08: isLocked:false8: isHeldByCurrentThread:false8: Awaiting...Write thread exit.java.lang.IllegalMonitorStateException atjava.util.concurrent.locks.ReentrantLock$Sync.tryRelease(Unknown Source) atjava.util.concurrent.locks.AbstractQueuedSynchronizer.release(Unknown Source) at java.util.concurrent.locks.AbstractQueuedSynchronizer.fullyRelease(Unknown Source) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(Unknown Source) at Foo$1.run(LockTest.java:44)

问题是:根据http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/Condition.html#await() ,当线程返回时,保证持有该锁。但从输出中我们看到await()返回后,它并没有重新获取锁。这是一个错误还是我犯了一些错误?

最佳答案

According to http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/Condition.html#await(), when the thread returns it is guaranteed to hold this lock.

确实如此,但它也说线程在调用方法之前必须持有锁:

The current thread is assumed to hold the lock associated with this Condition when this method is called. It is up to the implementation to determine if this is the case and if not, how to respond. Typically, an exception will be thrown (such as IllegalMonitorStateException) and the implementation must document that fact.

这与“普通”监视器(Object#wait)的工作方式相同:开始等待时必须持有锁(在 Object#wait 的情况下使用同步块(synchronized block),此处使用 Lock#lock)。然后锁将被释放,您等待。当等待结束时,你也再次持有锁。

关于Java Condition 在await() 返回后无法重新获取与其关联的锁(ReentrantLock),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17824875/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com