Java 并发系列十二 : Balking模式-再谈线程安全的单例模式

前言

感谢王宝令老师极客时间的并发课程

业务场景

我们经常使用的的编辑器功能,如果内容发生了变更 执行自动存盘操作,如果没有发生变更,则不进行存盘操作。这个场景如果利用 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 方案需要你更加谨慎。

你可能感兴趣的:(Java 并发系列十二 : Balking模式-再谈线程安全的单例模式)