前言
感谢王宝令老师极客时间的并发课程
业务场景
我们经常使用的的编辑器功能,如果内容发生了变更 执行自动存盘操作,如果没有发生变更,则不进行存盘操作。这个场景如果利用 Balking 模式该如何实现呢?
Balking 模式的经典实现
Balking 模式本质上是一种规范化的解决“多线程版本的 if”的方案, 对于上面自动保存的例子,使用Balking 模式规范化周的写入如下:
boolean changed = false;
void save() {
synchronized (this) {
if (!changed) {
return;
}
changed = false;
}
//执行存盘操作
//execSave();
}
void edit() {
//编辑内容,并修改变更状态标识
change();
}
void change() {
synchronized (this) {
changed = true;
}
}
将edit() 方法中对共享变量changed 的操作赋值操作抽取到了change() 中,这样做的好处就是将并发逻辑和业务逻辑分开。
用 volatile 实现 Balking 模式
前面我们用synchronized 实现了Balking 模式,,这种实现方式最为稳妥,建议你实际工作中也使用上述模式。不过某些场景下也可以使用volatile 来实现。
总结
Balking 模式和 Guarded Suspension 模式从实现上看似乎没有多大的关系, Balking 模式只需要用到互斥锁就能实现,而Guarded Suspension 模式需要用到管程种种高级并发原语,但是从应用的角度来讲,他们解决的都是“线程安全的 if”语义, 不同之处在于,Guarded Suspension 模式会等待 if 条件为真, 而 Balking 模式不会等待。
Balking 模式的经典实现是使用互斥锁,你可以使用 Java 语言内置 synchronized,也可以使用 SDK 提供 Lock;如果你对互斥锁的性能不满意,可以尝试采用 volatile 方案,不过使用 volatile 方案需要你更加谨慎。
网友评论