1. DCL 的目的
Double Check Lock 是多线程环境下为提高延迟初始化效率而被广泛使用的一种方式。我们常常会使用延迟初始化,以降低服务启动时间。
/**
* code 1.1
*/
@NotThreadSafe
public class Client {
private LazyInitClass instance ;
public LazyInitClass getInstance() {
if(instance == null)
instance = new LazyInitClass("LazyInitClassFieldName") ;
return instance ;
}
}
上面的代码是典型的延迟初始化的例子。当上面的例子暴露在多线程环境下时,便会出现各种问题。最明显的错误:方法会返回多个 LazyInitClass 对象。
/**
* code 1.2
*/
@NotThreadSafe
public class Client {
private LazyInitClass instance ;
public synchronized LazyInitClass getInstance() {
if(instance == null)
instance = new LazyInitClass("LazyInitClassFieldName") ;
return instance ;
}
}
上面的代码在方法层面使用了 synchronized 关键字,每次调用 getInstance 方法都进行同步,的确可以有效避免多线程环境下多次调用 getInstance 得到不同的 LazyInitClass 对象。但当 instance 初始化完成后,同步便没有了意义。同步则成为影响 getInstance 性能的关键。有没有一种方法,可以在初始化时进行正确的同步,初始化完成后又避免同步呢?于是 DCL 出现了。
/**
* code 1