1.什么是Guarded Suspension设计模式
Suspension是“挂起”、“暂停”的意思, 而Guarded则是“担保”的意思, 连在一起就是确保挂起。当线程在访问某个对象时,发现条件不满足,就暂时挂起等待条件满足时再次访问, 这一点和Balking设计模式刚好相反(Balking在遇到条件不满足时会放弃) 。
Guarded Suspension设计模式是很多设计模式的基础, 比如生产者消费者模式, WorkerThread设计模式, 等等, 同样在Java并发包中的Blocking Queue中也大量使用到了Guarded Suspension设计模式。
2.Guarded Suspension的示例
import java.util.LinkedList;public class GuardedSuspensionQueue {// 定义存放Integer类型的queueprivate final LinkedList<Integer> queue = new LinkedList<>();// 定义queue的最大容量为100private final int LIMIT = 100;// 往queue中插入数据,如果queue中的元素超过了最大容量,则会陷入阻塞public void offer(Integer data) throws InterruptedException {synchronized (this) {// 判断queue的当前元素是否超过了LIMITwhile(queue.size()>LIMIT) {// 挂起当前线程,使其陷入阻塞this.wait();}// 插入元素并且唤醒take线程queue.addLast(data);this.notifyAll();}}// 从队列中获取元素,如果队列此时为空,则会使当前线程阻塞public Integer take() throws InterruptedException {synchronized (this) {while(queue.isEmpty()) {this.wait();}// 通知offer线程可以继续插入数据了this.notifyAll();return queue.removeFirst();}}}
在Guarded Suspension Queue中, 我们需要保证线程安全的是queue, 分别在take和offer方法中对应的临界值是queue为空和queue的数量>=100, 当queue中的数据已经满时, 如果有线程调用offer方法则会被挂起(Suspension) , 同样, 当queue没有数据的时候,调用take方法也会被挂起。
Guarded Suspension模式是一个非常基础的设计模式, 它主要关注的是当某个条件(临界值)不满足时将操作的线程正确地挂起,以防止出现数据不一致或者操作超过临界值的控制范围。
