Two possibilities can be
b. bar.Notify() : Since your thread is waiting on bar object you can invoke bar.notify() and if you are lucky JVM will notify your thread but again i said if you are "lucky".
So to make sure your thread gets notified try below
bar.Notifyall() : Now this will notify all the threads that are waiting for bar object , Here bar object is the lock and this will make sure that your thread gets the notification.
Form javadoc:
"Wakes up a single thread that is waiting on this object's monitor. If any threads are waiting on this object, one of them is chosen to be awakened. The choice is arbitrary and occurs at the discretion of the implementation. A thread waits on an object's monitor by calling one of the wait methods."
Also
invoking notify() is equivalent to this.notify() which means the currently executing object is the lock object and invoking this code means that it will notify all the threads that are waiting on the currently executing object.
Also remember notify() , notifyAll() and wait() must always be used from synchronized code or else you will get
"java.lang.IllegalMonitorStateException": Current thread is not the owner
Form javadoc:
This method should only be called by a thread that is the owner of this object's monitor. A thread becomes the owner of the object's monitor in one of three ways:
* By executing a synchronized instance method of that object.
* By executing the body of a synchronized statement that synchronizes on the object.
* For objects of type Class, by executing a synchronized static method of that class.
The above code will throw exeception because the current thread, Main thread is not the owner of the lock object [this] because the method
test() is not synchronized or notify is not invoked in a synchronized block that locks on this object.