您的位置 首页 java

等待唤醒机制规范化之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 Suspension又被称为Guarded Wait 模式、Spin Lock 模式(因为使用了 while 循环去等待),多线程版本if(单线程场景中if语句不需要等待主线程阻塞将没有线程执行了,if判断条件也不会发生变化,而多线程下当前线程的判断结果是有可能被别的线程所篡改的)。

文章来源:智云一二三科技

文章标题:等待唤醒机制规范化之Guarded Suspension模式

文章地址:https://www.zhihuclub.com/180672.shtml

关于作者: 智云科技

热门文章

网站地图