diff --git a/guarded-suspension/README.md b/guarded-suspension/README.md index 8cd64aae1..9dc39f2c2 100644 --- a/guarded-suspension/README.md +++ b/guarded-suspension/README.md @@ -15,6 +15,78 @@ Use Guarded suspension pattern to handle a situation when you want to execute a ## Applicability Use Guarded Suspension pattern when the developer knows that the method execution will be blocked for a finite period of time +## Explanation + +Real world example + +> When we reserve a dining room online and arrive to find it unready, the manager has it cleaned while we wait. +> Once ready, we're escorted to the room. This process exemplifies the Guarded Suspension pattern. + +In plain words + +> Guarded Suspension pattern is used when one thread waits for the result of another thread's execution. + +Wikipedia says + +> In concurrent programming, Guarded Suspension manages operations requiring a lock +> and a precondition, delaying execution until the precondition is met. + +**Programmatic Example** + +The `GuardedQueue` class encapsulates a queue, and provides two synchronized methods, `get` and `put`. +The `get` method waits if the queue is empty, and the `put` method adds an item to the queue and notifies waiting threads: + +```java +public class GuardedQueue { +private final Queue sourceList = new LinkedList<>(); + + public synchronized Integer get() { + while (sourceList.isEmpty()) { + try { + wait(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + return sourceList.peek(); + } + + public synchronized void put(Integer e) { + sourceList.add(e); + notify(); + } +} + +public class App { +public static void main(String[] args) { +GuardedQueue guardedQueue = new GuardedQueue(); +ExecutorService executorService = Executors.newFixedThreadPool(3); + + // Here we create the first thread which is supposed to get from guardedQueue + executorService.execute(guardedQueue::get); + + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + // Here we create the second thread which is supposed to put to guardedQueue + executorService.execute(() -> { + guardedQueue.put(20); + }); + + executorService.shutdown(); + try { + executorService.awaitTermination(30, TimeUnit.SECONDS); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} +``` + + ## Related patterns * Balking