Notifies all the threads waiting for a condition to change. Threads will return
from the wait invocation once they can reacquire the object's lock.
public final voidnotify()
Notifies at most one thread waiting for a condition to change. You cannot
choose which thread will be notified, so use this form of notify only when
you are sure you know which threads are waiting for what at which times. If
you are not sure of any of these factors, you should use notifyAll.
If no threads are waiting when either notifyAll or notify is invoked, the notification is not remembered.
If a thread subsequently decides to wait, an earlier notification will have no effect on it. Only notifications
that occur after the wait commences will affect a waiting thread.
You can invoke these methods only from within synchronized code, using the lock for the object on which
they are invoked. The invocation can be directly made from the synchronized code, or can be made indirectly
from a method invoked in such code. You will get an IllegalMonitorStateException if you attempt
to invoke these methods on an object when you don't hold its lock.
When a wait completes because the time-out period expires, there is no indication that this occurred rather
than the thread being notified. If a thread needs to know whether or not it timed out, it has to track elapsed
time itself. The use of a time-out is a defensive programming measure that allows you to recover when some
condition should have been met but for some reason (probably a failure in another thread) has not. Because
the lock of the object must be reacquired, the use of a time-out cannot guarantee that wait will return in a
finite amount of time.
It is also possible that some virtual machine implementations will allow so-called "spurious wakeups" to
occurwhen a thread returns from wait without being the recipient of a notification, interruption, or time-out.
This is another reason that wait should always be performed in a loop that tests the condition being waited
on.
Exercise 14.6: Write a program that prints the elapsed time each second from the start of execution, with
another thread that prints a message every fifteen seconds. Have the message-printing thread be notified by
the time-printing thread as each second passes by. Add another thread that prints a different message every
seven seconds without modifying the time-printing thread.
14.6. Thread Scheduling
Threads perform different tasks within your programs and those tasks can have different importance levels
attached to them. To reflect the importance of the tasks they are performing, each thread has a priority that is
used by the runtime system to help determine which thread should be running at any given time. Programs can
be run on both single- and multiprocessor machines and you can run with multiple threads or a single thread,
so the thread scheduling guarantees are very general. On a system with N available processors, you will
usually see N of the highest-priority runnable threads executing. Lower-priority threads generally run only
when higher-priority threads are blocked (not runnable). But lower-priority threads might, in fact, run at other
times to prevent starvationa feature generally known as priority agingthough you cannot rely on it.
A running thread continues to run until it performs a blocking operation (such as wait, sleep, or some
types of I/O) or it is preempted. A thread can be preempted by a higher-priority thread becoming runnable or
because the thread scheduler decides it's another thread's turn to get some cyclesfor example, time slicing
limits the amount of time a single thread can run before being preempted.