I know that there are a few threads open regarding this topic, but I'm just looking for a VERY ELEMENTARY example of how to use wait() and notify() in Java. By "VERY ELEMENTARY," I mean simply printing something out. Thanks.
EDIT: Here's what I have tried thus far and I get an IllegalMonitorStateException:
public void waiting() {
for(int i = 0; i < 10; i++) {
if(i == 5)
try {
this.wait();
} catch (InterruptedException e) {
}
else
System.out.println(i);
}
System.out.println("notify me now");
this.notify();
}
wait and notify are used in synchronized block while using threads to suspend and resume where left off.
Wait immediately looses the lock, whereas Nofity will leave the lock only when the ending bracket is encountered.
public class Mythread implements Runnable{
public synchronized void goo(){
System.out.println("Before Wait");
wait();
System.out.println("After Wait");
}
public synchronized void foo(){
System.out.println("Before Notify");
notify();
System.out.println("After Notify");
}
public class Test{
public static void main(String[] args){
Thread t = new Thread(new Mythread);
t.start();
}
}
Your IllegalMonitorStateException is due to the fact that you must synchronize on the object before calling wait or notify. So
this.wait
needs to be
synchronized(this) {
this.wait();
}
Your example won't run because you'll never get to the notify call... as soon as your thread hits wait, it will suspend and advance no further. For wait / notify to work, you have to have two threads. One thread suspends when the wait method is invoked, and eventually, the second thread calls synchronized(this) { this.notify() } to cause the first thread to wake up and continue executing below the wait call.
The synchronization is required because you would ordinarily check some condition before waiting, ie,
synchronized(this) {
if(! this.isReady) {
this.wait();
}
}
You need to synchronize to make sure no other thread changes the state of the isReady flag between the line where you check the variable and the line where you wait. So your notify code would
synchronized(this) {
isReady = true;
this.notify();
}
Now the order of the method calls doesn't matter. If you notify first, no thread will wake up, but that's ok, because you aren't going to sleep since isReady = true. If you go to sleep first, isReady = true does nothing, but the notify call wakes up the thread. Finally, the synchronization ensures that you don't check the variable in thread A, then have thread B set the variable and notify (doing nothing), then have thread A go to sleep and never wake up.
Hope that helps.
wait() and notify() are used to synchronise threads: a thread can be told to wait(), and will not continue doing anything until it receives the notify() call.
The basic idea with these functions is that wait() suspends a thread (puts it to sleep), and notify() causes a thread to pick up where it left when it went to sleep.
Take a look at: this or just look up simple prodcuer consumer problem java on google. I am sure you will find something to suit your needs.
See this example on guarded blocks from the oracle java site - it includes a worked example of a simple producer-consumer problem.
Related
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();
}
This question was asked to me in an interview. Before I had told him this,
Once a thread enters any synchronized method on an instance, no other
thread can enter any other synchronized method on the same instance.
Consider the snippet:
Q1:
public class Q1 {
int n;
boolean valueSet = false;
synchronized int get() {
while (!valueSet)
try {
wait();
} catch (InterruptedException e) {
System.out.println("InterruptedException caught");
}
System.out.println("Got: " + n);
valueSet = false;
notify();
return n;
}
synchronized void put(int n) {
while (valueSet)
try {
wait();
} catch (InterruptedException e) {
System.out.println("InterruptedException caught");
}
this.n = n;
valueSet = true;
System.out.println("Put: " + n);
notify();
}
}
Producer1:
public class Producer1 implements Runnable {
Q1 q;
Producer1(Q1 q) {
this.q = q;
new Thread(this, "Producer").start();
}
#Override
public void run() {
int i = 0;
while (true) {
q.put(i++);
}
}
}
Consumer1
public class Consumer1 implements Runnable {
Q1 q;
Consumer1(Q1 q) {
this.q = q;
new Thread(this, "Consumer").start();
}
#Override
public void run() {
while (true) {
q.get();
}
}
}
PC1:
public class PC1 {
public static void main(String args[]) {
Q1 q = new Q1();
new Producer1(q);
new Consumer1(q);
System.out.println("Press Control-C to stop.");
}
}
So, he asked as soon as you have created this thread new Producer1(q), then according to you, the synchronized int get() method must have been locked by the same thread, i.e, by new Producer1(q) when it accessed synchronized int put(). I said yes.
But I checked in eclipse, get is callable by new Consumer1(q). The program works perfect.
Where am I going wrong?
O/P:
The call to wait() will release the monitor for the time waiting.
That's what is documented for Object.wait():
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.
Once a thread enters any synchronized method on an instance, no other
thread can enter any other synchronized method on the same instance.
What you forgot to add here is "except if the lock is released".
...and it is the case in your example, when calling wait.
The documentation specify :
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.
Since the lock is released, you step in the other method (and the condition is true because the boolean was modified). Once in the other method, you release the lock again, then call notify and you wake up the old thread which terminates (re-modify boolean to pass the condition in other method, and notify). That way you step between both methods ad-infinitum.
wait() and notify() is acts as a signal between threads, to control the threads to do or to not do the stuff.
The program works perfect because here 2 threads (Producer, Consumer) which fight for the one lock (monitor). When Consumer aquires the lock (Q1 object) then Producer is waiting for the lock. When Consumer finishes his work it release the lock. Consumer releases the lock also when wait() method has been called, because wait() sets thread to Waiting state with lock release. It's time for Producer to aquire the lock and does his work. When Producer thread notify() calls then Consumer continue his work (when aquired the lock). The same is right for Producer.
Resume: Q1 object is a lock for all threads. If it aquired someone then others are blocked and the answer is - it not possible to get an access at the same time to the get(), put() methods more then 2 threads.
I think that the question is ambiguous. (E.g., what does "accessible" mean?)
IMO, a good interview question should not have a right answer and a wrong answer. A good interview question should be a conversation starter, that gives you an opportunity to show how much you know about the subject.
When I am asking the interview questions, I like a candidate who can see through the question, and get down to the underlying mechanism. E.g.,
What the JLS guarantees is that no two threads can be _synchronized_
on the same instance at the same time...
Then we could explore questions like, how could two threads enter the same synchronized method at the same time? (e.g., synchronized on different instances), how could two threads be in the same synchronized method for the same instance at the same time (one of them could be in a wait() call), ...
A thread can not access a synchronized block of code unless it has aquired a lock on the object that guards the block. In your case, the synchronized keyword uses the lock of the object in which it has been declared. So as long as a thread is executing get(), no other thread can execute the put().
If you apply this, when put() sets the value, it notifies consumer which accepts the value. The code should work even after you have removed the wait() and notify() calls from both get and put methods
I have found the blow code in a project. But i cant understand why the only notify() method is in synchronized block .
synchronized(this){
notify();
}
Is this code logical and if so what is the real purpose ?
You're supposed to call notify only from a thread that owns the object's monitor. From the documentation:
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.
(My emphasis)
notify( ) wakes up the first thread that called wait( ) on the same object.
class ThreadB extends Thread{
int total;
#Override
public void run(){
synchronized(this){
for(int i=0; i<100 ; i++){
total += i;
}
notify();
}
}
Like above example, we use notify to send information message(hey i finished my work, wake up !) to other thread which is waiting. So at your question, it is not meaningful
To understand why it makes sense, consider that there have to be other blocks synchronized on the same object, that will be waken up by this block.
Take a look at this:
http://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html
This is not necessarily incorrect but definitely a bad sign. Somewhere else in that code, there will be an unconditional wait. E.g.:
synchronized(this) {
wait();
}
this might be working correctly now. But, if notify is ever executed before wait this will result in a deadlock.
Usually you want to wait on some condition:
synchronized(this) {
while(!this.flag) {
this.wait();
}
}
and use notify like this:
synchronized(this) {
this.flag = true;
this.notify();
}
This will never deadlock on it's own and it's clear what we are waiting for.
I made this sample to understand how Wait-Notify works:
public class WaitingTest implements Runnable {
Thread b = new Thread();
int total;
public static void main(String[] args){
WaitingTest w = new WaitingTest();
}
public WaitingTest(){
b.start();
synchronized(b){
try{
System.out.println("Waiting for b to complete...");
b.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("Total is: " + total);
}
}
#Override
public void run(){
synchronized(b){
for(int i=0; i<100 ; i++){
total += i;
System.out.println(total);
}
b.notify();
}
}
}
But I'm stuck here for hours and I can't understand why it's not quite working. My output should be more than 0, but its always zero...I was wondering if its becuase of the usage of different threads, but Im not really sure..What am I missing?
I think you have some serious holes in your understanding. You've declared a Thread
Thread b = new Thread();
and started it in the constructor
b.start();
That Thread will start and die right away since it has no Runnable attached to it.
It just so happens that when a Thread dies, it calls notify() on itself and since you are synchronized on that same Thread object, your wait()ing thread will be awoken. You also have a race here. If the Thread ends before the main thread reaches the wait(), you will be deadlocked.
Also, there is no reason for run() to be called, which is why total remains 0.
Any object can be synchronized on, it doesn't have to be a Thread. And since Thread has that weird behavior of notify()ing itself, you probably shouldn't use it.
You should go through both the Thread tutorials and the synchronization tutorials.
Apart from the problem with how you have arranged your threads, you have a incorrect use of wait()/notify()
notify() is stateless. If no thread is waiting, nothing will be notified. If you wait() later it will not be notified.
wait() can wake spuriously. Just because wait() woke doesn't mean anything notified it.
This means you need to associate wait/notify with state (in fact it's rather pointless without it)
For example.
// to notify
synchronized(lock) {
signalled = true;
lock.notify();
}
// to wait
synchronized(lock) {
while(!signalled)
lock.wait();
}
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