问题描述
我有这样的结构:
锁包装器-用于存储锁,条件和响应中的对象
I have structure something like this:
Lock wrapper - is used to store lock, condition and an object from response
public class LockWrapper{
private Lock lock;
private Condition myCondition;
private MyObject myObject;
public LockWrapper(Lock lock, Condition myCondition) {
this.lock = lock;
this.myCondition = myCondition;
}
public Condition getMyCondition() {
return myCondition;
}
public MyObject getMyObject() {
return myObject;
}
public void setObject(MyObject myObject) {
this.myObject = myObject;
}
public Lock getLock() {
return lock;
}
}
任务-推入线程池执行.它向服务器发起请求,然后等待服务器响应.
Task - pushed into a thread pool for execution. It initiates requests to a server and then waits for server responses.
public class MyTask implements Runnable{
private Lock lock = new ReentrantLock();
private Condition myCondition = lock.newCondition();
private MyWebSocketAPI api;
public MyTask(MyWebSocketAPI api) {
this.api = api;
}
@Override
public void run() {
lock.lock();
try {
// long randomLong = generateRandomLong();
api.sendRequest(randomLong, new LockWrapper(lock, myCondition));
myCondition.await();
//do something after we got a response
} finally{
lock.unlock();
}
}
}
WebSocket-获取请求并通知任务有关响应
WebSocket - gets requests and notifies tasks about responses
public abstract class MyWebSocketAPI extends WebSocketClient {
//...
private Map<Long, LockWrapper> lockWrappers = new ConcurrentHashMap<>();
public void sendRequest(Long id, LockWrapper lockWrapper){
this.lockWrappers.put(id, lockWrapper);
//processRequest
}
@Override
public void onMessage(String message) {
LockWrapper lockWrapper = lockWrappers.get(message.get(0).getAsLong());
lockWrapper.getLock().lock();
try{
lockWrapper.setMyObject(new MyObject(message));
this.lockWrappers.put(message.get(0).getAsLong(), lockWrapper);
lockWrapper.getMyCondition().signalAll();
} finally {
lockWrapper.getLock().unlock();
}
}
//...
}
第lockWrapper.getMyCondition().signalAll();
行引发异常:
java.lang.IllegalMonitorStateException: null
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.signalAll(AbstractQueuedSynchronizer.java:1954)
为什么当我尝试通知任务我们有它们的对象时,我的条件会引发此异常?我是在某个地方犯了错误还是Java不允许共享条件?
Why my conditions throw this exception when I try to notify tasks that we got their objects? Did I make a mistake somewhere or Java doesn't allow shared conditions?
推荐答案
这是我在Task
中的错误.问题是我在方法运行中同时创建了全局和局部的Lock and Condition.锁和条件的名称相同.在某些情况下,我使用的是lock
,在某些情况下,则使用的是this.lock
(但这是两个不同的锁).结果,在方法onMessage
中,我的Condition和Lock没有连接在一起.删除重复项后,一切正常.
It was my error in the Task
. The problem was that I was creating Lock and Condition both global and local in method run. Lock and condition had the same name. In some cases I was using lock
and in some cases this.lock
(But it was two different locks). As a result, in method onMessage
I had Condition and Lock which were not connected together.After I removed duplicates everything works.
这篇关于类之间的Java共享条件引发IllegalMonitorStateException:null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!