Aries1991
Aries1991

Reputation: 19

java.lang.IllegalMonitorStateException when condition.wait

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;
        }
    }
}

the java.lang.IllegalMonitorStateException will happen when i use ReentrantLock to wait, but it works well when i use synchronized , i can'not explain it. The reason is that reentrantLock is unlock before condition.wait(),but i don't know why. if someone can help me,i have submit the code to https://github.com/shanhm1991/demo_io.git

Upvotes: 2

Views: 652

Answers (1)

Erwin Bolwidt
Erwin Bolwidt

Reputation: 31299

That's because you're calling the wrong method. You should call await() rather than wait() on a Condition object:

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

You're currently calling wait which is the Object.wait() method, which requires you to be synchronized on the object that you are calling it on. But that's not what you want, you want the specific wait functionality of the Condition class, and that is only available through the method await.

Upvotes: 3

Related Questions