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

State

Condition

inc

dec

top

value == MAX

no

yes

middle

MIN < value < MAX

yes

yes

bottom

value == MIN

yes

no


 
 
 
 
 
 
 

Tracking State Variables

public class BoundedCounterVSW implements BoundedCounter {
  static final int BOTTOM = 0;
  static final int MIDDLE = 1;
  static final int TOP = 2;
  protected int state_ = BOTTOM; // the state variable
  protected long count_ = MIN;
  public synchronized long value() { return count_; }
  public synchronized void inc() {
    while (state_ == TOP)
      try { wait(); } catch(InterruptedException ex) {};
    ++count_;
    checkState();
  }
  public synchronized void dec() {
    while (state_ == BOTTOM)
      try { wait();} catch(InterruptedException ex) {};
    --count_;
    checkState();
  }
  protected synchronized void checkState() {
    int oldState = state_;
    if (count_ == MIN) state_ = BOTTOM;
    else if (count_ == MAX) state_ = TOP;
    else state_ = MIDDLE;
    if (state_ != oldState &&
      (oldState == TOP || oldState == BOTTOM))
        notifyAll();
  }
}
 
 

Balking

 

public class BalkingBoundedCounter {
  protected long count_ = BoundedCounter.MIN;
  public synchronized long value() { return count_; }
  public synchronized void inc() throws CannotIncrementException {
    if (count_ >= BoundedCounter.MAX)
      throw new CannotIncrementException();
    else
      ++count_;
  }
  public synchronized void dec() throws CannotDecrementException {
    if (count_ <= BoundedCounter.MIN)
      throw new CannotDecrementException();
    else
      --count_;
  }
}
 
 
 
 
 
 

Optimistic Policies

  1. a means of detecting failure
  2. a policy for dealing with failure
  3. a mechanism to deal with the consequences of failure
    1. provisional action: only update copies and do not make them permanent until it is known that there has not been a failure (data base updating)
    2. rollback/recovery: update the state variables, but keep enough information around to "rollback" their values to the proper state prior to the "fault" (optimistic distributed simulation)