Guarded Suspension Pattern

Intent

Use Guarded suspension pattern to handle a situation when you want to execute a method on object which is not in a proper state.

Wikipedia Says

In concurrent programming, guarded suspension is a software design pattern for managing operations that require both a lock to be acquired and a precondition to be satisfied before the operation can be executed. The guarded suspension pattern is typically applied to method calls in object-oriented programs, and involves suspending the method call, and the calling thread, until the precondition (acting as a guard) is satisfied.

Source code

Implementation is based on GuardedQueue, which has two methods: get and put, the condition is that we cannot get from empty queue so when thread attempt to break the condition we invoke Object's wait method on him and when other thread put an element to the queue he notify the waiting one that now he can get from queue.

Class Diagram

Class diagram of Guarded Suspension Pattern

Step 1:  Create GuardedQueue class which is an implementation for Guarded Suspension Pattern.
Guarded suspension pattern is used to handle a situation when you want to execute a method on an object which is not in a proper state.
public class GuardedQueue {
  private static final Logger LOGGER = LoggerFactory.getLogger(GuardedQueue.class);
  private final Queue<Integer> sourceList;

  public GuardedQueue() {
    this.sourceList = new LinkedList<>();
  }

  /**
   * @return last element of a queue if queue is not empty
   */
  public synchronized Integer get() {
    while (sourceList.isEmpty()) {
      try {
        LOGGER.info("waiting");
        wait();
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
    LOGGER.info("getting");
    return sourceList.peek();
  }

  /**
   * @param e number which we want to put to our queue
   */
  public synchronized void put(Integer e) {
    LOGGER.info("putting");
    sourceList.add(e);
    LOGGER.info("notifying");
    notify();
  }
}
Step 2 : Let's test Guarded Suspension Pattern.
public class App {
  /**
   * Example pattern execution
   *
   * @param args - command line args
   */
  public static void main(String[] args) {
    GuardedQueue guardedQueue = new GuardedQueue();
    ExecutorService executorService = Executors.newFixedThreadPool(3);

    //here we create first thread which is supposed to get from guardedQueue
    executorService.execute(() -> {
          guardedQueue.get();
        }
    );
   
    try {
      Thread.sleep(2000);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    executorService.execute(() -> {
          guardedQueue.put(20);
        }
    );
    executorService.shutdown();
    try {
      executorService.awaitTermination(30, TimeUnit.SECONDS);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }

}

Applicability

Use Guarded Suspension pattern when the developer knows that the method execution will be blocked for a finite period of time.

Related patterns

Comments