Information Technology Reference
In-Depth Information
5.6.4
Identifying condition variables
How should a programmer decide what condition variables a shared object
needs?
A systematic way to approach this problem is to consider each method and
ask, \When can this method wait?" Then, you can map each situation in which
a method can wait to a condition variable.
A programmer has considerable freedom in deciding how many condition
variables a class should have and what each should represent. One option is to
add add a condition variable corresponding to each situation in which a call to
the method must wait|perhaps creating a distinct condition variable for each
method that can block.
Example: Blocking Bounded Queue with two condition variables. In our
blocking bounded queue example, if the queue is full insert() must wait until
someone removes an item, so we create a condition variable itemRemoved .
Similarly, if the queue is empty remove() must wait until someone inserts an
item, so we create a condition variable itemAdded . It is fairly natural in this
case to create two condition variables, itemAdded to wait until the queue has
items and itemRemoved to wait until the queue has space.
Alternatively, a single condition variable can often suce. In fact, early
versions of Java defined a single condition variable per object and did not al-
low programmers to allocate additional ones, so this approach was effectively
mandated by the language. Under this approach, any thread that waits for any
reason uses that condition variable; if the condition variable is used by differ-
ent threads waiting for different reasons, then any thread that makes a state
change that could allow one or more other threads to proceed broadcasts on
that variable.
Example: Blocking Bounded Queue with one condition variable. It is
also possible to implement the blocking bounded queue with a single condition
variable somethingChanged on which both threads in insert() or threads in
remove() can wait. If we choose this approach, insert() and remove() will
need to Broadcast() rather than Signal() to ensure that the right threads get
a chance to run.
More complex programs make these trade-offs more interesting.
Example: ResourceManager. For example, imagine a ResourceManager
class that allows a calling thread to request exclusive access of any subset of
n distinct resources. One could imagine creating 2 n condition variables so that
a requesting thread could wait on a condition variable representing exactly its
desired combination and the signaling on all affected condition variables when
a resource becomes free. However, it may be simpler in this case to have a
single condition variable on which requesting threads wait and to broadcast on
that condition whenever a resource is freed.
Search WWH ::




Custom Search