Java Reference
In-Depth Information
Performance Tip 23.5
In most cases, a non-fair lock is preferable, because using a fair lock can decrease program
performance.
Condition Objects and Interface
Condition
If a thread that owns a
Lock
determines that it cannot continue with its task until some
condition is satisfied, the thread can wait on a
condition object
. Using
Lock
objects allows
you to explicitly declare the condition objects on which a thread may need to wait. For
example, in the producer/consumer relationship, producers can wait on
one
object and
consumers can wait on
another
. This is not possible when using the
synchronized
key-
words and an object's built-in monitor lock. Condition objects are associated with a spe-
cific
Lock
and are created by calling a
Lock
's
newCondition
method, which returns an
object that implements the
Condition
interface (of package
java.util.concur-
rent.locks
). To wait on a condition object, the thread can call the
Condition
's
await
method (analogous to
Object
method
wait
). This immediately releases the associated
Lock
and places the thread in the
waiting
state for that
Condition
. Other threads can then
try to obtain the
Lock
. When a
runnable
thread completes a task and determines that the
waiting
thread can now continue, the
runnable
thread can call
Condition
method
signal
(analogous to
Object
method
notify
) to allow a thread in that
Condition
's
waiting
state
to return to the
runnable
state. At this point, the thread that transitioned from the
waiting
state to the
runnable
state can attempt to reacquire the
Lock
. Even if it's able to
reacquire
the
Lock
, the thread still might not be able to perform its task at this time—in which case
the thread can call the
Condition
's
await
method to
release
the
Lock
and reenter the
wait-
ing
state. If multiple threads are in a
Condition
's
waiting
state when
signal
is called, the
default implementation of
Condition
signals the longest-waiting thread to transition to
the
runnable
state. If a thread calls
Condition
method
signalAll
(analogous to
Object
method
notifyAll
), then all the threads waiting for that condition transition to the
run-
nable
state and become eligible to reacquire the
Lock
. Only one of those threads can obtain
the
Lock
on the object—the others will wait until the
Lock
becomes available again. If the
Lock
has a
fairness policy
, the longest-waiting thread acquires the
Lock
. When a thread is
finished with a shared object, it must call method
unlock
to release the
Lock
.
Error-Prevention Tip 23.5
When multiple threads manipulate a shared object using locks, ensure that if one thread
calls method
await
to enter the
waiting
state for a condition object, a separate thread
eventually will call
Condition
method
signal
to transition the thread waiting on the
condition object back to the
runnable
state. If multiple threads may be waiting on the
condition object, a separate thread can call
Condition
method
signalAll
as a safeguard
to ensure that all the waiting threads have another opportunity to perform their tasks. If
this is not done, starvation might occur.
Common Programming Error 23.2
An
IllegalMonitorStateException
occurs if a thread issues an
await
, a
signal
, or a
signalAll
on a
Condition
object that was created from a
ReentrantLock
without hav-
ing acquired the lock for that
Condition
object.