Reputation: 19
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
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