2
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

Aries1991
  • 19
  • 2
  • 3
    Possible duplicate of [IllegalMonitorStateException on wait() call](https://stackoverflow.com/questions/1537116/illegalmonitorstateexception-on-wait-call) – Vince Sep 15 '17 at 06:11
  • @VinceEmigh That is not a duplicate of this specific problem, see the accepted answer. – Mark Rotteveel Sep 15 '17 at 09:40

1 Answers1

3

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.

Erwin Bolwidt
  • 30,799
  • 15
  • 56
  • 79