1.什么是Guarded Suspension设计模式

Suspension是“挂起”、“暂停”的意思, 而Guarded则是“担保”的意思, 连在一起就是确保挂起。当线程在访问某个对象时,发现条件不满足,就暂时挂起等待条件满足时再次访问, 这一点和Balking设计模式刚好相反(Balking在遇到条件不满足时会放弃) 。
Guarded Suspension设计模式是很多设计模式的基础, 比如生产者消费者模式, WorkerThread设计模式, 等等, 同样在Java并发包中的Blocking Queue中也大量使用到了Guarded Suspension设计模式。

2.Guarded Suspension的示例

  1. import java.util.LinkedList;
  2. public class GuardedSuspensionQueue {
  3. // 定义存放Integer类型的queue
  4. private final LinkedList<Integer> queue = new LinkedList<>();
  5. // 定义queue的最大容量为100
  6. private final int LIMIT = 100;
  7. // 往queue中插入数据,如果queue中的元素超过了最大容量,则会陷入阻塞
  8. public void offer(Integer data) throws InterruptedException {
  9. synchronized (this) {
  10. // 判断queue的当前元素是否超过了LIMIT
  11. while(queue.size()>LIMIT) {
  12. // 挂起当前线程,使其陷入阻塞
  13. this.wait();
  14. }
  15. // 插入元素并且唤醒take线程
  16. queue.addLast(data);
  17. this.notifyAll();
  18. }
  19. }
  20. // 从队列中获取元素,如果队列此时为空,则会使当前线程阻塞
  21. public Integer take() throws InterruptedException {
  22. synchronized (this) {
  23. while(queue.isEmpty()) {
  24. this.wait();
  25. }
  26. // 通知offer线程可以继续插入数据了
  27. this.notifyAll();
  28. return queue.removeFirst();
  29. }
  30. }
  31. }

在Guarded Suspension Queue中, 我们需要保证线程安全的是queue, 分别在take和offer方法中对应的临界值是queue为空和queue的数量>=100, 当queue中的数据已经满时, 如果有线程调用offer方法则会被挂起(Suspension) , 同样, 当queue没有数据的时候,调用take方法也会被挂起。
Guarded Suspension模式是一个非常基础的设计模式, 它主要关注的是当某个条件(临界值)不满足时将操作的线程正确地挂起,以防止出现数据不一致或者操作超过临界值的控制范围。