模式单例模式
Java语言在不考虑线程安全的情况下,经典的单例模式实现:构造函数私有化是为了在外部不能够创建实例,只能该类的内部构造实例。
在考虑线程安全的情况下,可以有多种实现方式,每种实现方式的效率是不一样的。
在后续的几个步骤中介绍在考虑线程安全的情况下的单例模式的实现。
线程安全的关键点是创建实例和赋值的过程,可能有多个线程执行了创建,然后进行了赋值。
所以单例模式的线程安全都是保证创建实例并赋值的过程是串行的,即只能有一个线程可以执行。
转载或论者示认引用路本文内容请注明来源于百科回价答最简单的方式,就是在获取单例的函数上,加上synchronized关键字,这种实现方式的效率是最低的:在函数上用synchronized关键字范围大了。
实际上,只需要在创建实例的过程保证只能一个线程可以执行就可以了的例子:例子是用了双重检查(double-checked locking)。
在发现未创建实例时,用synchronized保护创建实例的过程。
变量使用了volatile关键字,主要是为了防止优化行为导致数据不同步。
比如:假设线程A的singleton缓存在寄存器,线程B执行了创建并赋值,此时线程A的singleton并不会刷新。
在Java语言说明文档(Java Language Specification)的描述中,说类的初始化过程(class initialization)是串行的,即只能单个线程执行。
那么就可以利用这一点来保证单例模式的线程安全。
这种是效率最高的。
接下来介绍基于语言特性的线程安全单例模式的例子。
直接在类成员中创建:这种方式会在类第一次调用的时候初始化,那就不一定是获取单例的函数的调用,比如调用output时,也会初始化成员变量。
定里日别争联务,话拉值毛细。
居于上一个例子可能存在的问题,采用嵌套类的方式,就能保证在调用获取单例的函数时,才创建单例: