间的Java共享条件引发IllegalMonitorStateE

间的Java共享条件引发IllegalMonitorStateE

本文介绍了类之间的Java共享条件引发IllegalMonitorStateException:null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这样的结构:
锁包装器-用于存储锁,条件和响应中的对象

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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-29 19:08