第三部分-并发设计模式32:Balking设计模式

1.Balking模式

线程安全的单例模式

2.多线程的if

多线程if条件快速放弃的方案

3.案例精选

编辑器自动保存功能
每隔一段时间自动执行存盘操作,前提是文件做过修改。如果文件没有做过操作,不要等待,快速放弃存盘。和上一篇的Guarder Suspension在这一点有很大的不同。Guarder Suspension是强制等待,直到条件满足才执行下一步操作。

代码样例:
AutoSaveEditor.java


class AutoSaveEditor{
  //文件是否被修改过
  boolean changed=false;
  //定时任务线程池
  ScheduledExecutorService ses = 
    Executors.newSingleThreadScheduledExecutor();
  //定时执行自动保存
  void startAutoSave(){
    ses.scheduleWithFixedDelay(()->{
      autoSave();
    }, 5, 5, TimeUnit.SECONDS);  
  }
  //自动存盘操作
  void autoSave(){
    if (!changed) {
      return;
    }
    changed = false;
    //执行存盘操作
    //省略且实现
    this.execSave();
  }
  //编辑操作
  void edit(){
    //省略编辑逻辑
    ......
    changed = true;
  }
}

4.以上代码是否是线程安全的?

不是,对共享变量changed的读写没有使用同步

5.如何保证线程安全呢?

方法级加锁,synchronized 修饰,但锁范围太大,性能不好了

如何优化性能?只对共享变量的操作进行加锁,锁的是AutoSaveEditor对象


//自动存盘操作
void autoSave(){
  synchronized(this){
    if (!changed) {
      return;
    }
    changed = false;
  }
  //执行存盘操作
  //省略且实现
  this.execSave();
}
//编辑操作
void edit(){
  //省略编辑逻辑
  ......
  synchronized(this){
    changed = true;
  }
}  

6.多线程版本的if,就叫做balking模式

Balking设计模式,本质上是一种规范化解决多线程if的方案。

修改代码,对共享变量changed的赋值操作抽到了change方法中 ,好处是并发处理逻辑和业务逻辑区分开,使得符合Balking设计模式


boolean changed=false;
//自动存盘操作
void autoSave(){
  synchronized(this){
    if (!changed) {
      return;
    }
    changed = false;
  }
  //执行存盘操作
  //省略且实现
  this.execSave();
}
//编辑操作
void edit(){
  //省略编辑逻辑
  ......
  change();
}
//改变状态
void change(){
  synchronized(this){
    changed = true;
  }
}

7.单例模式的Balking设计模式使用

双重检查方案


class Singleton{
  private static volatile 
    Singleton singleton;
  //构造方法私有化  
  private Singleton() {}
  //获取实例(单例)
  public static Singleton 
  getInstance() {
    //第一次检查
    if(singleton==null){
      synchronize(Singleton.class){
        //获取锁后二次检查
        if(singleton==null){
          singleton=new Singleton();
        }
      }
    }
    return singleton;
  }
}

8.总结

Balking 模式只需要互斥锁就能解决,而Guarded Suspension 要用管程并发原语。
Guarder Suspension 模式会等待多线程if条件为真,而Balking 模式不会等待,快速放弃。

posted @ 2021-06-10 17:26  SpecialSpeculator  阅读(73)  评论(0编辑  收藏  举报