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类型的queue
private final LinkedList<Integer> queue = new LinkedList<>();
// 定义queue的最大容量为100
private final int LIMIT = 100;
// 往queue中插入数据,如果queue中的元素超过了最大容量,则会陷入阻塞
public void offer(Integer data) throws InterruptedException {
synchronized (this) {
// 判断queue的当前元素是否超过了LIMIT
while(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模式是一个非常基础的设计模式, 它主要关注的是当某个条件(临界值)不满足时将操作的线程正确地挂起,以防止出现数据不一致或者操作超过临界值的控制范围。