mirror of
https://github.com/tiennm99/java-design-patterns.git
synced 2026-10-13 22:16:03 +00:00
docs: Explanation for guarded suspension (#2752)
* translation for step-builder and table-module and unit-of-work and update-method and value-object to Chinese * fix a translation error * Add explanation for guarded suspension * delete previous modifications
This commit is contained in:
1 parent
f5747d85f1
commit
4575879264
1 file changed
+72
@@ -15,6 +15,78 @@ Use Guarded suspension pattern to handle a situation when you want to execute a
|
|||||||
## Applicability
|
## Applicability
|
||||||
Use Guarded Suspension pattern when the developer knows that the method execution will be blocked for a finite period of time
|
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<Integer> 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
|
## Related patterns
|
||||||
|
|
||||||
* Balking
|
* Balking
|
||||||
Reference in new issue
Block a user