等待唤醒规范化之Guarded Suspension模式
Guarded Suspension模式
什么是Guarded Suspension模式
Guarded Suspension直译为保护性挂起,其核心是一个受保护的方法,该方法在执行其所需要真正执行的操作时需要满足特定的条件,当条件状态不满足时,执行受保护方法的线程挂起并进入等待状态,直到条件状态满足该线程才能继续执行。
现实场景
在我们生活中其实有很多这种场景例如,我们去外面用餐提前在网上预定了一个包间,然后到时间过去用餐,找到大堂经理这时经理发现包间还没收拾,就叫服务员马上收拾,让我们稍等片刻,大堂经理发现服务员收拾完毕后就会将我们带到指定包间,这个过程就是一个典型的Guarded Suspension模式。
这时我们可以将处理流程结构化如下所示
我们需要注意的是Guarded Suspension模式的条件变量这里指的就是餐厅是否打扫干净这个条件。
场景语义化如下
// 大堂经理
class GuardedObject<T> {
// 受保护对象 餐厅
private T obj;
private final Lock lock = new ReentrantLock();
private final Condition done = lock.newCondition();
public GuardedObject(T obj){
this.obj = obj;
}
// 获取受保护对象
public T get(Predicate<T> p){
lock.lock();
try {
while (!p.test(obj)){
System.out.println("====大堂经理询问是否可以就餐====");
done.await(1, TimeUnit.SECONDS);
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
return obj;
}
// 给服务员用,打扫完包间就将包间的状态改为干净
public void onChanged(T obj){
lock.lock();
try {
this.obj = obj;
done.signalAll();
}finally {
lock.unlock();
}
}
}
测试代码如下
public static void main(String[] args) throws InterruptedException {
// obj=1表示餐厅还没收拾 obj=0表示收拾好了可以用餐
GuardedObject<Integer> guardedObject = new GuardedObject(1);
// 顾客就餐
Thread t1 = new Thread(()->{
System.out.println(Thread.currentThread().getName()+"==顾客进入餐厅");
// d
Integer integer = guardedObject.get(e -> {
return 0 == e;
});
System.out.println(Thread.currentThread().getName()+"==顾客可以用餐");
});
// 服务员打扫
Thread t2 = new Thread(()->{
try {
System.out.println(Thread.currentThread().getName()+"==服务员开始打扫");
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
guardedObject.onChanged(0);
System.out.println(Thread.currentThread().getName()+"==服务员打扫完毕");
});
t1.start();
Thread.sleep(500);
t2.start();
t1.join();
t2.join();
}
执行结果如下
总结
Guarded Suspension模式其本质就是等待唤醒机制的一种规范,如果解决实际问题需要或多或少的对Guarded Suspension功能进行扩展(一般是多一个等待队列,任务按照顺序出队处理)。
Guarded Suspension又被称为Guarded Wait 模式、Spin Lock 模式(因为使用了 while 循环去等待),多线程版本if(单线程场景中if语句不需要等待主线程阻塞将没有线程执行了,if判断条件也不会发生变化,而多线程下当前线程的判断结果是有可能被别的线程所篡改的)。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~