balking模式
文章目录
balking 模式理解
我们提到可以用“多线程版本的 if”来理解 Guarded Suspension 模式,不同于单线程中的 if,这个“多线程版本的 if”是需要等待的,而且还很执着,必须要等到条件为真。但很显然这个世界,不是所有场景都需要这么执着,有时候我们还需要快速放弃。
|
|
如果你深入地分析一下这个示例程序,你会发现,示例中的共享变量是一个状态变量,业务逻辑依赖于这个状态变量的状态:当状态满足某个条件时,执行某个业务逻辑,其本质其实不过就是一个 if 而已,放到多线程场景里,就是一种“多线程版本的 if”。这种“多线程版本的 if”的应用场景还是很多的,所以也有人把它总结成了一种设计模式,叫做Balking 模式。
|
|
用 volatile 实现 Balking 模式
前面我们用 synchronized 实现了 Balking 模式,这种实现方式最为稳妥,建议你实际工作中也使用这个方案。不过在某些特定场景下,也可以使用 volatile 来实现,但使用 volatile 的前提是对原子性没有要求。
Balking 模式有一个非常典型的应用场景就是单次初始化,下面的示例代码是它的实现。这个实现方案中,我们将 init() 声明为一个同步方法,这样同一个时刻就只有一个线程能够执行 init() 方法;init() 方法在第一次执行完时会将 inited 设置为 true,这样后续执行 init() 方法的线程就不会再执行 doInit() 了。
那有没有办法可以优化一下它的性能呢?
办法当然是有的,那就是经典的双重检查(Double Check)方案,下面的示例代码是其详细实现。在双重检查方案中,一旦 Singleton 对象被成功创建之后,就不会执行 synchronized(Singleton.class){}相关的代码,也就是说,此时 getInstance() 方法的执行路径是无锁的,从而解决了性能问题。不过需要你注意的是,这个方案中使用了 volatile 来禁止编译优化
|
|
文章作者 LYR
上次更新 2021-08-17