notify() and wait()

J

Jack

I have two threads: thread1 and thread2 and use myObject for
synchronization.

Object myObject = new Object();

If thread1 calls myObject.notify() first, then thread2 calls
myObject.wait(). The wait() still blocks thread2, right?

In general, it is difficult to control the timing of notify() and wait
() call. How to prevent this situation.

When I call notify() and wait(), must I put them in a synchronized
block? like:

synchronized(myObject)
{
myObject.notify();
}

Thanks.
 
J

Joshua Cranmer

If thread1 calls myObject.notify() first, then thread2 calls
myObject.wait(). The wait() still blocks thread2, right?
Right.

In general, it is difficult to control the timing of notify() and wait
() call. How to prevent this situation.

Well, notify/wait has specific semantics. In pthreads, the equivalent
feature is the condition variable: you want to wait (hence the method
name) until a condition becomes true; another thread will notify you
that the condition is true.

If you have a notify which is only being called once, you're probably
using the wrong thing. A classic example of wait/notify is if you're
trying to manage a buffer where different threads consume and produce:
you wait when the buffer has too much or too little (two separate
variables), and you notify when you remove or add, respectively.
When I call notify() and wait(), must I put them in a synchronized
block?

Yes. Actually, you should also put your condition check inside the
synchronized block as well. In a while loop (to avoid spurious wakeup).
 
E

Eric Sosman

I have two threads: thread1 and thread2 and use myObject for
synchronization.

Object myObject = new Object();

If thread1 calls myObject.notify() first, then thread2 calls
myObject.wait(). The wait() still blocks thread2, right?

Yes. If thread1 calls myObject.notify() one million times
and then thread2 calls myObject.wait(), thread2 blocks. A
notification is a one-shot deal; there's no memory of how often
or when notify() has been called. notify() just awakens some
thread that happens to be in wait() at the moment; if nobody
is waiting, nobody is awakened. Ever.
In general, it is difficult to control the timing of notify() and wait
() call. How to prevent this situation.

When wait() returns, it does not mean "There *is* something
to be done," but "There *may be* something to be done." Java,
of course, has no idea what the "something" might be, nor what
"ready to be done" requires. You, the programmer, know these
things, and you, the programmer write the appropriate tests.

So: The thread that waits doesn't just wait(), it first
checks whether there's something to do already. And after the
wait() returns, it checks *again* just in case some other thread
came along and took care of whatever it was. So (anticipating
the answer to your next question)

Thing toBeDone;
synchronized (myObject) {
while (! myObject.somethingIsReadyToBeDone())
myObject.wait();
toBeDone = myObject.removeTheReadySomething();
}
toBeDone.doWhateverItIs();

Study how this works. It synchronizes on myObject (which
is probably something more specialized than a plain Object) to
"stabilize" it so no other thread's activity will disturb things
while this thread is deciding what to do. Then it checks whether
there's something to be done. If there is, it plows straight
ahead without calling wait() at all -- there's work to be done,
so there's nothing to wait for. Otherwise it calls wait(), which
does two things: It puts the thread to sleep, and it releases
the lock on myObject so other threads can synchronize on it.

Before wait() returns, it re-acquires the lock so myObject
is once again stable. Now we re-check for readiness; an unknown
amount of time may have passed since somebody else called notify(),
and in that interval things might have changed -- so we check
again, knowing that nothing further will change while we've got
the myObject lock. If there's nothing to be done (some other
thread got there first), we loop around and wait() again.

Eventually, the test says "there's something to do," and
we escape from the while loop. Then *before* releasing the lock
we grab the "work order" or whatever from myObject, or otherwise
indicate that "we got it; nobody else need try." We do this
while still holding the lock, because if we were to let go some
other thread could jump in and mess us up. Finally, when we've
got all the information we need to carry on with our task, we
can drop the lock and go about our business.
When I call notify() and wait(), must I put them in a synchronized
block? like:

synchronized(myObject)
{
myObject.notify();
}

Yes, for both the notify() or notifyAll() and for the wait().
 
T

Tom Anderson

I have two threads: thread1 and thread2 and use myObject for
synchronization.

Object myObject = new Object();

If thread1 calls myObject.notify() first, then thread2 calls
myObject.wait(). The wait() still blocks thread2, right?

In general, it is difficult to control the timing of notify() and wait
() call. How to prevent this situation.

I suspect that what you really want is a CountDownLatch:

http://java.sun.com/javase/6/docs/api/java/util/concurrent/CountDownLatch.html

Like it says:

A CountDownLatch initialized with a count of one serves as a simple
on/off latch, or gate: all threads invoking await wait at the gate until
it is opened by a thread invoking countDown().

So, the thread which wants to wait should call await(), and the one which
wants to notify should call countDown().

tom
 
T

Tom Anderson

Not necessarily.

Oh, absolutely - but it's what i suspect.
The original question could have been exactly the same if, for example,
the OP were trying to build a blocking queue from first principles. I
think the first step in building communication between threads should be
to look at java.util.concurrent, without preconceptions, to see whether
any of its classes does the job.

This is excellent advice, and i'm sorry i made you have to give it twice!
I thought that the OP might benefit from a suggestion of something
specific to look at within that package - it's a fairly broad collection
of classes, and can be daunting to a beginner.

tom
 
J

Jack

Not necessarily. The original question could have been exactly the same
if, for example, the OP were trying to build a blocking queue from first
principles. I think the first step in building communication between
threads should be to look at java.util.concurrent, without
preconceptions, to see whether any of its classes does the job.

Patricia

Thank you all for your replies.
My application is that: Thread1 wakes up every five hours to do a job;
Thread2 wakes up Thread1 if the application is to be shut down. So
Thread2 is mainly for preventing the program from hanging there.
So the code is like:

Static boolean conditionIsTrue = false;

//For Thread1:
while(conditionIsTrue)
{
doTheJob();
Synchronized(myObject)
{
myObject.wait(//for 5 hours);
}
}

//For Thread2:
shutDown()
{
conditionIsTrue = false;
Synchronized(myObject)
{
myObject.notify();
}
}

Can java.util.concurrent solve my problem?

Thanks.
 
L

Lew

Jack said:
My application is that: Thread1 wakes up every five hours to do a job;
Thread2 wakes up Thread1 if the application is to be shut down. So
Thread2 is mainly for preventing the program from hanging there.
So the code is like:

Static boolean conditionIsTrue = false;

//For Thread1:
while(conditionIsTrue)
{
    doTheJob();
    Synchronized(myObject)
    {
         myObject.wait(//for 5 hours);
    }

}

//For Thread2:
shutDown()
{
    conditionIsTrue = false;
    Synchronized(myObject)
    {
         myObject.notify();
    }

}

I note that you have ignored the requirement elucidated by Patricia
Shanahan, among others here:
That will cause grief.
Can java.util.concurrent solve my problem?

Yes, although there are other ways, of course. In this thread Tom
Anderson has shown at least one example of a java.util.concurrent
approach, using
<http://java.sun.com/javase/6/docs/api/java/util/concurrent/
CountDownLatch.html>
as you may have noticed.

Why don't you read through the Javadocs for the various
java.util.concurrent classes and packages and consider whether they'll
help you? It looks like there are several things there that could be
of use to you, depending on the subtleties of your requirements that
we cannot know.

Read and study /Java Concurrency in Practice/ by Brian Goetz, et al.
It explains 'wait()' and 'notify()' (including the need to test the
condition within the 'synchronized' block) and many of the concurrency
library structures, along with best practices for getting the most out
of them. Brian Goetz (one of the authors of the concurrency
libraries, btw) and others also write extensively on these matters in
IBM Developerworks and elsewhere.
 
L

Lew

Jack said:
So the code is like:

Static boolean conditionIsTrue = false;

//For Thread1:
while(conditionIsTrue)
{
    doTheJob();
    Synchronized(myObject)
    {
         myObject.wait(//for 5 hours);
    }

}

//For Thread2:
shutDown()
{
    conditionIsTrue = false;
    Synchronized(myObject)
    {
         myObject.notify();
    }

}

Can java.util.concurrent solve my problem?

Side note (i.e., not an answer to the primary question):
You need to spell Java's keywords correctly. The snippets you show
here won't compile.

I suggest that you write an SSCCE to illustrate the concepts for
yourself. Then, even if you don't share the whole SSCCE here, the
snippets you do copy and paste will be correct. The compiler can be a
very powerful training tool.

<http://sscce.org/>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,186
Members
46,740
Latest member
JudsonFrie

Latest Threads

Top