State Dependent Action
(Lea - Chapt. 4)
Overview of the problem
· "Safety concerns for classes with state-dependent actions revolve around the considerations necessary to complete a design so that you take into account all possible combinations of messages and states," (Lea)
Alternative policies
"check-and-act (or pessimistic) policies"
"try and see (or optimistic) policies"
Considerations in
determining a reasonable policy for a "host" object
Representing State
Guarded Suspension
public class GuardedClass
{ //generic code sketch
protected boolean cond_
= false;
protected synchronized void awaitCond() {
while (!cond) {try(wait();) catch
(InterruptedException ex) {}
}
}
public synchronized void guardedAction() {
awaitCond(); // actions
}
}
protected void spinWaitUntilCond()
{
while (!cond_)
Thread.currentThread().yield();
}
· possible actions:
o ignore by re-evaluation and re-waiting
o terminate thread
o exit the method (passing exception to next level up)
o perform cleanup
o user intervention
· liveness: wakeup waiting threads when conditions change
o encapsulate assignments in public method and notifyAll
o may cause too many notifications
o notifyAll is expensive operation
o "best practice" is to place notify and notifyAll as last operation in method (remember: notify is "notify and continue")
public
class BoundedCounterV1 implements BoundedCounter {
protected
long count_ = MIN;
public
synchronized long value() { return count_; }
public
synchronized void inc() { awaitIncrementable();
setCount(count_ + 1);
}
public
synchronized void dec() {
awaitDecrementable();
setCount(count_ - 1);
}
protected synchronized void setCount(long newValue) {
count_ = newValue;
notifyAll(); // wake up any thread depending on new
value
}
protected synchronized void awaitIncrementable() {
while (count_ >= MAX)
try { wait(); } catch(InterruptedException ex) {};
}
protected synchronized void awaitDecrementable() {
while (count_ <= MIN)
try { wait(); } catch(InterruptedException ex) {};
}
}
public
class GuardedClassV2 {
protected boolean cond_
= false;
protected int nWaiting_
= 0; //count waiting threads
protected synchronized void awaitCond() {
++nWaiting; // count waiting
threads
try { wait(); } catch { InterruptedException
ex) {}
--nWaiting; // no longer waiting
}
protected synchronized void signalCond() {
if (cond_) //simulate notifyAll
for (int i = nWaiting_; i > 0 ; --i)
notify();
}
}
Tracking State in Objects