IllegalMonitorStateException on a synchronized call to a Lock Condition's signalAll() - java

I have:
static public final ReentrantLock lock = new ReentrantLock();
static public Condition my_condition = lock.newCondition();
in myClass_1 and in myClass_2 class I call:
synchronized (myClass_1.my_condition){
myClass_1.my_condition.signalAll();
}
This is giving me the java.lang.IllegalMonitorStateException. I am already synchronizing over the signall() call. What could be causing it?

This is because you are not getting the lock of ReentrantLock before signalling.
Read below important statements from ReentrantLock#newCondition
If this lock is not held when any of the Condition waiting or
signalling methods are called, then an IllegalMonitorStateException is
thrown.
Also, read below from Condition. Now, like you cannot call wait() if thread is not acquiring the lock, same you wait or signal conditions if lock is not acquired.
Where a Lock replaces the use of synchronized methods and statements,
a Condition replaces the use of the Object monitor methods.
Bottom line: Acquire the lock before waiting or signalling the Condition.
lock.lock(); //Get the lock
while(/* whatever is your condition in myClass_1 and myClass_2 */){ //Or negative condition you want, but some code logic condition...
my_condition.await();
}
my_condition_2.signal(); //If you want to notify one thread. Like in case of Java's blocking queue, if you want to notify one thread to put or take.
my_condition_2.signalAll(); //If you want to notify all threads.

Do not use synchronized with Locks. Locks and Conditions replace synchronized/wait/notify; they should never be used in combination with it.
The documentation for ReeantrantLock.newCondition states:
If this lock is not held when any of the Condition waiting or signalling methods are called, then an IllegalMonitorStateException is thrown.
Correct use of a Lock and Condition looks like this:
lock.lock();
try {
someFlag = true;
condition.signalAll();
} finally {
lock.unlock();
}
And elsewhere:
lock.lock();
try {
someFlag = false;
while (!someFlag) {
condition.await();
}
} finally {
lock.unlock();
}
All Condition.await* methods must be called in a while-loop that checks the data the Condition represents, since the await* methods are subject to spurious wakeups (just like the Object.wait* methods).

Related

How to create user defined SettableFuture in java [duplicate]

I am using multi-threading in java for my program.
I have run thread successfully but when I am using Thread.wait(), it is throwing java.lang.IllegalMonitorStateException.
How can I make a thread wait until it will be notified?
You need to be in a synchronized block in order for Object.wait() to work.
Also, I recommend looking at the concurrency packages instead of the old school threading packages. They are safer and way easier to work with.
EDIT
I assumed you meant Object.wait() as your exception is what happens when you try to gain access without holding the objects lock.
wait is defined in Object, and not it Thread. The monitor on Thread is a little unpredictable.
Although all Java objects have monitors, it is generally better to have a dedicated lock:
private final Object lock = new Object();
You can get slightly easier to read diagnostics, at a small memory cost (about 2K per process) by using a named class:
private static final class Lock { }
private final Object lock = new Lock();
In order to wait or notify/notifyAll an object, you need to be holding the lock with the synchronized statement. Also, you will need a while loop to check for the wakeup condition (find a good text on threading to explain why).
synchronized (lock) {
while (!isWakeupNeeded()) {
lock.wait();
}
}
To notify:
synchronized (lock) {
makeWakeupNeeded();
lock.notifyAll();
}
It is well worth getting to understand both Java language and java.util.concurrent.locks locks (and java.util.concurrent.atomic) when getting into multithreading. But use java.util.concurrent data structures whenever you can.
I know this thread is almost 2 years old but still need to close this since I also came to this Q/A session with same issue...
Please read this definition of illegalMonitorException again and again...
IllegalMonitorException is thrown to indicate that a thread has attempted to wait on an object's monitor or to notify other threads waiting on an object's monitor without owning the specified monitor.
This line again and again says, IllegalMonitorException comes when one of the 2 situation occurs....
1> wait on an object's monitor without owning the specified monitor.
2> notify other threads waiting on an object's monitor without owning the specified monitor.
Some might have got their answers... who all doesn't, then please check 2 statements....
synchronized (object)
object.wait()
If both object are same... then no illegalMonitorException can come.
Now again read the IllegalMonitorException definition and you wont forget it again...
Based on your comments it sounds like you are doing something like this:
Thread thread = new Thread(new Runnable(){
public void run() { // do stuff }});
thread.start();
...
thread.wait();
There are three problems.
As others have said, obj.wait() can only be called if the current thread holds the primitive lock / mutex for obj. If the current thread does not hold the lock, you get the exception you are seeing.
The thread.wait() call does not do what you seem to be expecting it to do. Specifically, thread.wait() does not cause the nominated thread to wait. Rather it causes the current thread to wait until some other thread calls thread.notify() or thread.notifyAll().
There is actually no safe way to force a Thread instance to pause if it doesn't want to. (The nearest that Java has to this is the deprecated Thread.suspend() method, but that method is inherently unsafe, as is explained in the Javadoc.)
If you want the newly started Thread to pause, the best way to do it is to create a CountdownLatch instance and have the thread call await() on the latch to pause itself. The main thread would then call countDown() on the latch to let the paused thread continue.
Orthogonal to the previous points, using a Thread object as a lock / mutex may cause problems. For example, the javadoc for Thread::join says:
This implementation uses a loop of this.wait calls conditioned on this.isAlive. As a thread terminates the this.notifyAll method is invoked. It is recommended that applications not use wait, notify, or notifyAll on Thread instances.
Since you haven't posted code, we're kind of working in the dark. What are the details of the exception?
Are you calling Thread.wait() from within the thread, or outside it?
I ask this because according to the javadoc for IllegalMonitorStateException, it is:
Thrown to indicate that a thread has attempted to wait on an object's monitor or to notify other threads waiting on an object's monitor without owning the specified monitor.
To clarify this answer, this call to wait on a thread also throws IllegalMonitorStateException, despite being called from within a synchronized block:
private static final class Lock { }
private final Object lock = new Lock();
#Test
public void testRun() {
ThreadWorker worker = new ThreadWorker();
System.out.println ("Starting worker");
worker.start();
System.out.println ("Worker started - telling it to wait");
try {
synchronized (lock) {
worker.wait();
}
} catch (InterruptedException e1) {
String msg = "InterruptedException: [" + e1.getLocalizedMessage() + "]";
System.out.println (msg);
e1.printStackTrace();
System.out.flush();
}
System.out.println ("Worker done waiting, we're now waiting for it by joining");
try {
worker.join();
} catch (InterruptedException ex) { }
}
In order to deal with the IllegalMonitorStateException, you must verify that all invocations of the wait, notify and notifyAll methods are taking place only when the calling thread owns the appropriate monitor. The most simple solution is to enclose these calls inside synchronized blocks. The synchronization object that shall be invoked in the synchronized statement is the one whose monitor must be acquired.
Here is the simple example for to understand the concept of monitor
public class SimpleMonitorState {
public static void main(String args[]) throws InterruptedException {
SimpleMonitorState t = new SimpleMonitorState();
SimpleRunnable m = new SimpleRunnable(t);
Thread t1 = new Thread(m);
t1.start();
t.call();
}
public void call() throws InterruptedException {
synchronized (this) {
wait();
System.out.println("Single by Threads ");
}
}
}
class SimpleRunnable implements Runnable {
SimpleMonitorState t;
SimpleRunnable(SimpleMonitorState t) {
this.t = t;
}
#Override
public void run() {
try {
// Sleep
Thread.sleep(10000);
synchronized (this.t) {
this.t.notify();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Thread.wait() call make sense inside a code that synchronizes on Thread.class object. I don't think it's what you meant.
You ask
How can I make a thread wait until it will be notified?
You can make only your current thread wait. Any other thread can be only gently asked to wait, if it agree.
If you want to wait for some condition, you need a lock object - Thread.class object is a very bad choice - it is a singleton AFAIK so synchronizing on it (except for Thread static methods) is dangerous.
Details for synchronization and waiting are already explained by Tom Hawtin.
java.lang.IllegalMonitorStateException means you are trying to wait on object on which you are not synchronized - it's illegal to do so.
Not sure if this will help somebody else out or not but this was the key part to fix my problem in user "Tom Hawtin - tacklin"'s answer above:
synchronized (lock) {
makeWakeupNeeded();
lock.notifyAll();
}
Just the fact that the "lock" is passed as an argument in synchronized() and it is also used in "lock".notifyAll();
Once I made it in those 2 places I got it working
I received a IllegalMonitorStateException while trying to wake up a thread in / from a different class / thread. In java 8 you can use the lock features of the new Concurrency API instead of synchronized functions.
I was already storing objects for asynchronous websocket transactions in a WeakHashMap. The solution in my case was to also store a lock object in a ConcurrentHashMap for synchronous replies. Note the condition.await (not .wait).
To handle the multi threading I used a Executors.newCachedThreadPool() to create a thread pool.
Those who are using Java 7.0 or below version can refer the code which I used here and it works.
public class WaitTest {
private final Lock lock = new ReentrantLock();
private final Condition condition = lock.newCondition();
public void waitHere(long waitTime) {
System.out.println("wait started...");
lock.lock();
try {
condition.await(waitTime, TimeUnit.SECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
lock.unlock();
System.out.println("wait ends here...");
}
public static void main(String[] args) {
//Your Code
new WaitTest().waitHere(10);
//Your Code
}
}
For calling wait()/notify() on object, it needs to be inside synchronized block. So first you have to take lock on object then would be possible to call these function.
synchronized(obj)
{
obj.wait()
}
For detailed explanation:
https://dzone.com/articles/multithreading-java-and-interviewspart-2
wait(), notify() and notifyAll() methods should only be called in syncronized contexts.
For example, in a syncronized block:
syncronized (obj) {
obj.wait();
}
Or, in a syncronized method:
syncronized static void myMethod() {
wait();
}

Object vs Condition, wait() vs await()

In the solution to an programming exercise concerning locks, I've noticed they were using an Object to syncronize on, so something like:
Lock lock = new ReentrantLock();
Object obj = new Object();
and in a method:
synchronized(obj){
obj.wait();}
my question is, could I have used a Condition instead, let's say:
Condition cond = lock.newCondition();
and then use, in the method,
cond.await()
instead, without putting it in a synhronized block?
edit: the solution:
How would I implement this with the Condition?
Yes. But you have to aquire the lock first. See the doc of Condition.await():
The current thread is assumed to hold the lock associated with this
Condition when this method is called. It is up to the implementation
to determine if this is the case and if not, how to respond.
Typically, an exception will be thrown (such as
IllegalMonitorStateException) and the implementation must document
that fact.
synchronized (obj) {
while (<condition does not hold>)
obj.wait();
... // Perform action appropriate to condition
}
is similar with
ReentrantLock lock = new ReentrantLock();
Condition cond = lock.newCondition();
lock.lock();
try {
while (<condition does not hold>)
cond.await();
}
} finally {
lock.unlock();
}

notifyall() not the last statement

Assume I have a Read/Write monitor implementation in Java.
Several Readers OR One Writer can access the database at any one time (not both)
class RWmonitor{
private int readers = 0;
private boolean writing = false;
public synchronized void StartRead(){ ..}
public synchronized void EndRead(){
notifyAll();
readers--;
}
public synchronized void StartWrite(){ ..}
public synchronized void EndWrite(){
notifyAll();
writing = false;
}
}
Now, does it matter if notifyAll() is not the last statement in the synchronized method?
Assume:
1) EndRead() executes
2) notifyAll() notifies all waiting threads
3) Then it reduces the reader count.
When it executes notifyAll(), will it just be more costly since the woken up threads would be waiting for the lock on RWmonitor to be released? (assuming the thread that has the lock on RWmonitor is still at readers--;)
It does not matter if it is the last statement.
To quote the javadoc for notifyAll():
The awakened threads will not be able to proceed until the current thread relinquishes the lock on this object.
No, it doesn't matter. The lock will still be held until the end of the synchronized block, and no threads will be able to wait on the lock in the intervening time. In fact it is slightly advantageous to have the notify first in that an exception may stop the update but not the notify.

java concurrency in practice 14.6

This code snippet from java concurrency in practice, I really don't understand.
#ThreadSafe
public class BoundedBuffer<V> extends BaseBoundedBuffer<V> {
// CONDITION PREDICATE: not-full (!isFull())
// CONDITION PREDICATE: not-empty (!isEmpty())
public BoundedBuffer(int size) { super(size); }
// BLOCKS-UNTIL: not-full
public synchronized void put(V v) throws InterruptedException {
while (isFull())
wait();
doPut(v);
notifyAll();
}
// BLOCKS-UNTIL: not-empty
public dsynchronize V take() throws InterruptedException {
while (isEmpty())
wait();
V v = doTake();
notifyAll();
return v;
}
}
the put and take methods are synchronized. If some thread is waiting in put method, no one can ever enter take or put method, So, in most of the cases, if a thread start to wait, it will wait for ever.
Am I miss-understand something?
It is synchronized but the wait() method released the lock if it waits -- that's how it works. The thread then blocks until it is notified. Once notified, it reacquires the lock and continues. To quote the Object.wait() javadocs:
Causes the current thread to wait until another thread invokes the java.lang.Object.notify() method or the java.lang.Object.notifyAll() method for this object. In other words, this method behaves exactly as if it simply performs the call wait(0).
The current thread must own this object's monitor. The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object's monitor to wake up either through a call to the notify method or the notifyAll method. The thread then waits until it can re-obtain ownership of the monitor and resumes execution.
I'd recommend doing some more reading about Java concurrency, specifically this section on guarded blocked.
It is more typical to specify specifically which object you are waiting and notifying. The wait() call really should be this.wait() and this.notifyAll() which makes it easier to be able to figure out which lock is being affected.

Waiting for an event in Java - how hard is it?

I have a thread that updates it's state from time to time and I want a second thread to be able to wait for the first thread to be done. Something like this:
Thread 1:
while(true) {
...do something...
foo.notifyAll()
...wait for some condition that might never happen...
...
}
Thread 2:
...
foo.wait();
...
Now this looks nice and all unless Thread 1's notifyAll() runs before Thread 2's wait(), in which case Thread 2 waits until Thread 1 notifies again (which might never happen).
My possible solutions:
a) I could use a CountDownLatch or a Future, but both have the problem that they inherently only run once. That is, in Thread 1's while loop, I would need to create a new foo to wait for each time and Thread 2 would need to ask which foo to wait for. I have a bad feeling about simply writing
while(true) {
foo = new FutureTask();
...
foo.set(...);
...wait for a condition that might never be set...
...
}
as I fear that at foo = new FutureTask(), what happens when someone waited for the old foo (for "some reason", set was not called, e.g. a bug in the exception handling)?
b) Or I could use a semaphore:
class Event {
Semaphore sem;
Event() { sem = new Semaphore(1); sem . }
void signal() { sem.release(); }
void reset() { sem.acquire(1); }
void wait() { if (sem.tryAcquire(1)) { sem.release(); } }
}
But I fear that there is some race condition, if multiple threads are wait()ing for it while another one signal()s and reset()s.
Question:
Is there nothing in the Java API that resembles the Windows Event behaviour? Or, if you despise Windows, something like golang's WaitGroup (i.e. a CountDownLatch that allows countUp())? Anything?
How to do it manually:
Thread 2 cannot simply wait because of spurious wakeup and in Java there is no way to know why Object.wait() returned. So I need a condition variable that stores whether the event is signalled or not. Thread 2:
synchronized(foo) {
while(!condition) {
foo.wait();
}
}
And Thread 1 of course sets condition to true in a synchronized block. Thanks to weekens for the hint!
Is there an existing class that wraps that behaviour?
Or do I need to copy and paste the code all over?
It is standard practice to change some state when performing notifyAll and to check some state when performing wait().
e.g.
boolean ready = false;
// thread 1
synchronized(lock) {
ready = true;
lock.notifyAll();
}
// thread 2
synchronized(lock) {
while(!ready)
lock.wait();
}
With this approach, it doesn't matter if thread 1 or thread 2 acquires the lock first.
Some coding analysis tools will give you a warning if you use notify or wait without setting a value or checking a value.
You could use a wait() with timeout, in which case you are not risking to wait forever. Also note that wait() may return even if there was no notify() at all, so, you'll need to wrap your wait inside some conditioned loop. That's the standard way of waiting in Java.
synchronized(syncObject) {
while(condition.isTrue()) {
syncObject.wait(WAIT_TIMEOUT);
}
}
(in your Thread 2)
Edit: Moved synchronized outside the loop.
The simplest way is just to say
firstThread.join();
This will be blocking until the first thread is terminated.
But you can implement the same using wait/notify. Unfortunately you have not posted your real code fragments but I guess that if wait does not exit when you call notify it happens because you did not put both into synchronized block. Pay attention that the "argument" of synchronized block must be the same for wait/notify pair.
I'd use a BlockingQueue between the two threads. Using wait and notify is so 5 minutes ago ;)
enum Event {
Event,
Stop;
}
BlockingQueue<Event> queue = new LinkedBlockingQueue<Event>();
// Thread 1
try {
while(true) {
...do something...
queue.put(Event.Event);
...wait for some condition that might never happen...
...
}
} finally {
// Tell other thread we've finished.
queue.put(Event.Stop};
}
// Thread 2
...
switch ( queue.take() ) {
case Event:
...
break;
default:
...
break;
}
Seems there is only ugly solutions. I solve it using AtomicBoolean as flag and some sleep to prevent high cpu usage and timeout for unexpected lost event...
Here my code:
somewhere in thread class:
private static final int WAIT_DELAY_MS_HACK = 5000; //ms
private static final AtomicBoolean NeedToExecute = new AtomicBoolean(false);
In working thread, that need to send wake signal:
public static final void SendSignalToExecute(){
synchronized(NeedToExecute){
NeedToExecute.set(true);
NeedToExecute.notify();
}
}
In the thread that must wait signal:
//To prevent infinite delay when notify was already lost I use WAIT_DELAY_MS_HACK in wait().
//To prevent false interruption on unknown reason of JM I use while and check of AtomicBoolean by NeedToExecute.get() in it.
//To prevent high CPU usage in for unknown persistant interruption in wait I use additional sleep():
while (!NeedToExecute.get()){
synchronized(NeedToExecute){
try {
NeedToExecute.wait(WAIT_DELAY_MS_HACK); //if notify() was sent before we go into wait() but after check in while() it will lost forever... note that NeedToExecute.wait() releases the synchronized lock for other thread and re-acquires it before returning
} catch (InterruptedException ex) { //here also may be sleep or break and return
}
}
sleep(100); //if wait() will not wait - must be outside synchronized block or it may cause freeze thread with SendSignalToExecute()... :(
}
NeedToExecute.set(false); //revert back to reenter check in next iteration, but I use it for one waited thread it cycle "do ... wait" if you use multiple thread you need to synchronise somehow this revert

Categories

Resources