条件.wait时的java.lang.IllegalMonitorStateException

时间:2017-09-15 06:10:43

标签: java

private static volatile AtomicInteger blockClientCount = new AtomicInteger(0);

private static Object lock = new Object();

private static Lock reentrantLock = new ReentrantLock();

private static Condition condition = reentrantLock.newCondition();    

@Override
public void run() {
    Random random = new Random(this.hashCode());
    while (true) {
        String request = random.nextInt(10) + "" + IOUtil.operators[random.nextInt(4)] + (random.nextInt(10) + 1);
        System.out.println(this.getName() + " send request:" + request);
        if (socketConnect()) {
            BufferedReader in = null;
            PrintWriter out = null;
            try {
                out = new PrintWriter(socket.getOutputStream(), true);
                in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                blockClientCount.incrementAndGet();

                reentrantLock.lock();
                try {
                    while (blockClientCount.get() % IOUtil.CLIENNT_NUM != 0) {
                        /**
                         * TODO java.lang.IllegalMonitorStateException
                         */
                        condition.wait();
                    }
                    condition.signalAll();
                } finally {
                    reentrantLock.unlock();
                }

                // synchronized (lock) {
                // while (blockClientCount.get() % IOUtil.CLIENNT_NUM != 0)
                // {
                // lock.wait();
                // }
                // lock.notifyAll();
                // }
                out.println(request);
                String response = in.readLine();
                System.out.println(this.getName() + " accept response:" + response);
            } catch (final Exception e) {
                e.printStackTrace();
            } finally {
                IOUtil.close(in);
                IOUtil.close(out);
            }
        }
        try {
            sleep(1000);
        } catch (InterruptedException e) {
            System.out.println(this.getName() + " was interrupted and stop");
            IOUtil.close(socket);
            break;
        }
    }
}

当我使用ReentrantLock等待时会发生java.lang.IllegalMonitorStateException,但是当我使用synchronized时它会正常工作,我无法解释它。 原因是reentrantLock在condition.wait()之前解锁,但我不知道为什么。 如果有人可以帮助我,我已将代码提交给https://github.com/shanhm1991/demo_io.git

1 个答案:

答案 0 :(得分:2)

那是因为你正在调用错误的方法。您应该在await()对象上致电wait()而不是Condition

reentrantLock.lock();
try {
    condition.await();
} finally {
    reentrantLock.unlock();
}

您当前正在调用wait这是Object.wait()方法,该方法要求您在要调用它的对象上进行同步。但这不是您想要的,您需要Condition类的特定等待功能,并且只能通过await方法获得。