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, the 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 |
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
Concurrency patterns
Design Pattern
Java
Comments
Post a Comment