Would someone explain why this situation is not working as I expected? I would really like to learn from my mistake but I do not understand why Java is throwing a particular error...
This is a situation where I want to restrict a certain section of a method to one thread at a time. I do not want to make the whole method synchronized (using the synchronized keyword and making it static)
I use one Boolean object as a lock and as a flag to indicate this one section is currently "busy".
One thread grabs a lock, sets it to true, does its work then grabs a lock again, sets it to false and calls notifyAll for anyone else waiting on that lock. But there's some quirky behavior causing it to fail which I don't get yet.
It goes like this:
import java.io.*;
import java.util.*;
import java.text.*;
import java.util.regex.*;
import java.util.zip.*;
public class Test implements Runnable {
public static void main (String[] args) {
try {
Thread t1 = new Thread(new Test("Thread 1"));
Thread t2 = new Thread(new Test("Thread 2"));
t1.start();
t2.start();
} catch (Exception e) {
e.printStackTrace();
}
}
static String id;
static Boolean isBusy = Boolean.FALSE;
public Test (String id) {
this.id = id;
}
public void run() {
try {
System.out.println(id+" starting");
synchronized (isBusy) {
if (isBusy.booleanValue()) {
System.out.println(id+" is waiting");
isBusy.wait();
System.out.println(id+" stopped waiting");
}
isBusy = Boolean.TRUE;
}
Thread.sleep(3000);
System.out.println(id+" ending");
synchronized (isBusy) {
isBusy = Boolean.FALSE; // LINE 50
System.out.println(id+" sending notifyAll");
isBusy.notifyAll(); // LINE 52
}
} catch (Exception e) {
System.out.println(id+" error");
e.printStackTrace();
}
}
}
What happens is one thread goes in and correctly grabs the lock and proclaims the section is busy while the other thread correctly waits. But when that thread is done, when I both set the busy flag to false AND call notifyAll I get the "java.lang.IllegalMonitorStateException: current thread not owner" on line 52 (the call to notifyAll).
If I comment out line 50 which unsets the flag, I then don''t have any problems... why is that?
Does line 50 implicitly release the lock? I had no idea that modifying the value of a lock releases it... what would I have to do to make this scenario work correctly?
thanks for you guidance and help!!!