condition.wait时发生java.lang.IllegalMonitorStateException

java

241 观看

1回复

9 作者的声誉

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,但是当我使用sync时,它工作得很好,我无法解释。原因是reentrantLock在condition.wait()之前是解锁的,但我不知道为什么。如果有人可以帮助我,我已将代码提交到https://github.com/shanhm1991/demo_io.git

作者: Aries1991 的来源 发布者: 2017 年 9 月 15 日

回应 1


2

25901 作者的声誉

决定

那是因为您在调用错误的方法。你应该叫await()而不是wait()一个上Condition对象:

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

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

作者: Erwin Bolwidt 发布者: 2017 年 9 月 15 日
32x32