Wait()返回后,Java条件无法重新获取与其关联的锁(ReentrantLock) import java.util.LinkedList; 导入java.util.concurrent.locks.Condition; 导入java.util.concurrent.locks.ReentrantLock; 福班{ 私有可重入锁; 私人条件; 私有线程; 私有链接列表(msgQueue); 公共食物({ _锁=新的可重入锁(); _cond=_lock.newCondition(); _msgQueue=newlinkedlist(); startThread(); } public void putMsg(字符串msg)引发异常{ _lock.lock(); _msgQueue.addLast(msg); _条件信号(); System.out.println(Thread.currentThread().getId()+“:信号写入线程”); _lock.unlock(); System.out.println(Thread.currentThread().getId()+“:Unlocked”); } 私有void startThread(){ _thr=新线程(){ 公开募捐{ _lock.lock(); while(true){ 试一试{ 而(!\msgQueue.isEmpty()){ 字符串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()+“:waiting…”); _条件等待(); System.out.println(Thread.currentThread().getId()+“:Write Thread aware”); }捕获(例外e){ e、 printStackTrace(); 打破 }最后{ 试一试{ _lock.unlock(); }捕获(例外e){ } } } System.out.println(“写入线程退出”); } }; _thr.start(); } } 公共类锁测试{ 公共静态void main(字符串[]args)引发异常{ Foo-Foo=新的Foo(); foo.putMsg(“味精1”); foo.putMsg(“味精2”); 睡眠(1000); foo.putMsg(“味精3”); } } 运行一次后的代码输出: 1:信号写入线程。 1:解锁。 1:信号写入线程。 1:解锁。 味精1 味精2 8:getHoldCount:1 8:isLocked:true 8:isHeldByCurrentThread:真 8:等待。。。 1:信号写入线程。 1:解锁。 8:写入线程唤醒 味精3 8:getHoldCount:0 8:已锁定:false 8:isHeldByCurrentThread:false 8:等待。。。 写入线程退出。 java.lang.IllegalMonitorStateException位于 位于的java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(未知源) java.util.concurrent.locks.AbstractQueuedSynchronizer.release(未知源)位于 位于的java.util.concurrent.locks.AbstractQueuedSynchronizer.fullyRelease(未知源) java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(未知源) 在Foo$1.run(LockTest.java:44)
问题是: 根据,当线程返回时,保证持有该锁。但是从输出中,我们可以看到,在await()返回后,它不会重新获得锁。这是一个错误还是我犯了一些错误 根据,当线程返回时,保证持有该锁 是的,但它还表示线程在调用方法之前必须持有锁: 调用此方法时,假定当前线程持有与此条件关联的锁。由实施部门确定是否存在这种情况,如果不是,如何应对。通常,将引发异常(例如IllegalMonitorStateException),实现必须记录该事实Wait()返回后,Java条件无法重新获取与其关联的锁(ReentrantLock) import java.util.LinkedList; 导入java.util.concurrent.locks.Condition; 导入java.util.concurrent.locks.ReentrantLock; 福班{ 私有可重入锁; 私人条件; 私有线程; 私有链接列表(msgQueue); 公共食物({ _锁=新的可重入锁(); _cond=_lock.newCondition(); _msgQueue=newlinkedlist(); startThread(); } public void putMsg(字符串msg)引发异常{ _lock.lock(); _msgQueue.addLast(msg); _条件信号(); System.out.println(Thread.currentThread().getId()+“:信号写入线程”); _lock.unlock(); System.out.println(Thread.currentThread().getId()+“:Unlocked”); } 私有void startThread(){ _thr=新线程(){ 公开募捐{ _lock.lock(); while(true){ 试一试{ 而(!\msgQueue.isEmpty()){ 字符串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()+“:waiting…”); _条件等待(); System.out.println(Thread.currentThread().getId()+“:Write Thread aware”); }捕获(例外e){ e、 printStackTrace(); 打破 }最后{ 试一试{ _lock.unlock(); }捕获(例外e){ } } } System.out.println(“写入线程退出”); } }; _thr.start(); } } 公共类锁测试{ 公共静态void main(字符串[]args)引发异常{ Foo-Foo=新的Foo(); foo.putMsg(“味精1”); foo.putMsg(“味精2”); 睡眠(1000); foo.putMsg(“味精3”); } } 运行一次后的代码输出: 1:信号写入线程。 1:解锁。 1:信号写入线程。 1:解锁。 味精1 味精2 8:getHoldCount:1 8:isLocked:true 8:isHeldByCurrentThread:真 8:等待。。。 1:信号写入线程。 1:解锁。 8:写入线程唤醒 味精3 8:getHoldCount:0 8:已锁定:false 8:isHeldByCurrentThread:false 8:等待。。。 写入线程退出。 java.lang.IllegalMonitorStateException位于 位于的java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(未知源) java.util.concurrent.locks.AbstractQueuedSynchronizer.release(未知源)位于 位于的java.util.concurrent.locks.AbstractQueuedSynchronizer.fullyRelease(未知源) java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(未知源) 在Foo$1.run(LockTest.java:44),java,locking,conditional-statements,Java,Locking,Conditional Statements,问题是: 根据,当线程返回时,保证持有该锁。但是从输出中,我们可以看到,在await()返回后,它不会重新获得锁。这是一个错误还是我犯了一些错误 根据,当线程返回时,保证持有该锁 是的,但它还表示线程在调用方法之前必须持有锁: 调用此方法时,假定当前线程持有与此条件关联的锁。由实施部门确定是否存在这种情况,如果不是,如何应对。通常,将引发异常(例如IllegalMonitorStateException),实现必须记录该事实 这与“普通”监视器(对象#等待)的工作方式相同:开始等待时必须持有锁(
这与“普通”监视器(对象#等待)的工作方式相同:开始等待时必须持有锁(对象#等待时使用同步块,此处使用锁#锁)。锁将被释放,您等待。等待结束后,您也会再次持有锁。您可以显示一些代码吗?我正在尝试发布我的代码,编辑器标记代码检查总是拒绝我的发布…最后,代码来了…是的,我在wait()之前持有锁,您可以看到run()方法中的第一条语句_lock.lock()。我将lock()放入while(true)中,代码可以正确运行,但我必须这样做吗?每次等待()返回后都需要锁定()吗?每次要等待()时都需要锁定()。您可能只需将lock()保持在顶部,但现在,每次迭代都有一个finally unlock()。
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 1
Msg 2
8: getHoldCount:1
8: isLocked:true
8: isHeldByCurrentThread:true
8: Awaiting...
1: Signal write thread.
1: Unlocked.
8: Write thread awaken
Msg 3
8: getHoldCount:0
8: isLocked:false
8: isHeldByCurrentThread:false
8: Awaiting...
Write thread exit.
java.lang.IllegalMonitorStateException at
java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(Unknown Source) at
java.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)