\file
Condition
.d
\brief
Condition
implements a condition variable for
a lock.
Written by Doug Lea with assistance from members of JCP JSR-166
Expert Group and released to the public domain, as explained at
http:
//creativecommons.org/licenses/publicdomain
Ported to D by Ben Hinkle.
Email comments and bug reports to ben.hinkle@gmail.com
revision 2.0
- interface
Condition
;
- \class
Condition
\brief Conditions (also known as condition queues or
condition variables) provide a means for one thread to
suspend execution (to "wait") until notified by another
thread that some state condition may now be true.
Because access to this shared state information occurs in different
threads, it must be protected, so a lock of some form is associated
with the condition. The key property that waiting for a condition
provides is that it atomically releases the associated
lock and suspends the current thread.
A
Condition
instance is intrinsically bound to a lock.
To obtain a
Condition
instance for a particular Lock
instance use its newCondition() method.
A
Condition
implementation can provide customized
behavior and semantics such as guaranteed ordering for
notifications, or not requiring a lock to be held when performing
notifications. If an implementation provides such specialized
semantics then the implementation must document those semantics.
Note that
Condition
instances are just normal objects
and can themselves be used as the target in a synchronized
statement. Acquiring the monitor lock of a
Condition
instance has no specified relationship with acquiring the Lock
associated with that
Condition
. It is recommended that to
avoid confusion you never use
Condition
instances in this
way, except perhaps within their own implementation.
Implementation Considerations
When waiting upon a
Condition
, a "spurious
wakeup" is permitted to occur, in general, as a
concession to the underlying platform semantics. This has little
practical impact on most application programs as a
Condition
should always be waited upon in a loop, testing
the state predicate that is being waited for. An implementation is
free to remove the possibility of spurious wakeups but it is
recommended that applications programmers always assume that they
can occur and so always wait in a loop.
- abstract void
wait
();
- Causes the current thread to
wait
until it is notified.
The lock associated with this Condition is atomically
released and the current thread becomes disabled for thread scheduling
purposes and lies dormant until one of three things happens:
- Some other thread invokes the notify method for this
Condition and the current thread happens to be chosen as the
thread to be awakened; or
- Some other thread invokes the notifyAll method for this
Condition; or
- A "spurious wakeup" occurs
In all cases, before this method can return the current thread must
re-acquire the lock associated with this condition. When the
thread returns it is guaranteed to hold this lock.
Implementation Considerations
The current thread is assumed to hold the lock associated
with this Condition when this method is called. It is
up to the implementation to determine if this is the case and
if not, how to respond.
- abstract long
waitNanos
(long nanosTimeout);
- Causes the current thread to wait until it is notified
or the specified waiting time elapses.
The lock associated with this condition is atomically
released and the current thread becomes disabled for thread scheduling
purposes and lies dormant until one of four things happens:
- Some other thread invokes the notify method for this
Condition and the current thread happens to be chosen as the
thread to be awakened; or
- Some other thread invokes the notifyAll method for this
Condition; or
- The specified waiting time elapses; or
- A "spurious wakeup" occurs.
In all cases, before this method can return the current
thread must re-acquire the lock associated with this
condition. When the thread returns it is guaranteed to
hold this lock.
The method returns an estimate of the number of nanoseconds
remaining to wait given the supplied nanosTimeout
value upon return, or a value less than or equal to zero if it
timed out. This value can be used to determine whether and how
long to re-wait in cases where the wait returns but an waited
condition still does not hold. Typical uses of this method take
the following form:
synchronized bool aMethod(long timeout, TimeUnit unit) {
long nanosTimeout = unit.toNanos(timeout);
while (!conditionBeingWaitedFor) {
if (nanosTimeout > 0)
nanosTimeout = theCondition.waitNanos(nanosTimeout);
else
return false;
}
// ...
}
Design note: This method requires a nanosecond argument so
as to avoid truncation errors in reporting remaining times.
Such precision loss would make it difficult for programmers to
ensure that total waiting times are not systematically shorter
than specified when re-waits occur.
Implementation Considerations
The current thread is assumed to hold the lock associated
with this Condition when this method is called. It is
up to the implementation to determine if this is the case and
if not, how to respond.
\param nanosTimeout the maximum time to wait, in nanoseconds
\return A value less than or equal to zero if the wait has
timed out; otherwise an estimate, that
is strictly less than the nanosTimeout argument,
of the time still remaining when this method returned.
- abstract bool
wait
(long time, TimeUnit unit);
- Causes the current thread to
wait
until it is notified
or the specified waiting time elapses. This method is behaviorally
equivalent to:
waitNanos(unit.toNanos(time)) > 0
\param time the maximum time to
wait
\param unit the time unit of the time argument.
\return false if the waiting time detectably elapsed
before return from the method, else true.
- abstract void
notify
();
- Wakes up one waiting thread.
If any threads are waiting on this condition then one
is selected for waking up. That thread must then re-acquire the
lock before returning from wait.
- abstract void
notifyAll
();
- Wake up all waiting threads.
If any threads are waiting on this condition then they are
all woken up. Each thread must re-acquire the lock before it can
return from wait.
|