一: 饱汉模式
[code lang=”java”]
/**
* 饱汉模式
* 懒加载
* 饱汉,即已经吃饱,不着急再吃,饿的时候再吃。
* 所以他就先不初始化单例,等第一次使用的时候再初始化,即“懒加载”。
* 好处: 启动快, 节省资源
* 坏处:线程不安全,if语句存在竞态条件
*/
public class Singleton1 {
private static Singleton1 st=null;
private Singleton1(){
}
public static Singleton1 getInstance(){
if(st==null){
return new Singleton1();
}
return st;
}
}[/code]
二: 饱汉模式变种1, 线程安全
[code lang=”java”]
/**
* 好处: 线程安全
* 坏处: 效率低,初始化后,synchronized锁也无法避开,getInstance串行执行
*
*/
public class Singleton1_1 {
private static Singleton1_1 st = null;
private Singleton1_1(){
}
public synchronized static Singleton1_1 getInstance(){
if(null == st){
st = new Singleton1_1();
}
return st;
}
}[/code]
三:饱汉模式变种2: 几乎懒加载+线程安全
[code lang=”java”]
/**
* 变种2的核心是DCL,看起来变种2似乎已经达到了理想的效果:懒加载+线程安全。
* 可惜的是,正如注释中所说,DCL仍然是线程不安全的,由于指令重排序,你可能会得到“半个对象”
*/
public class Singleton1_2 {
private static Singleton1_2 st = null;
private Singleton1_2() {
}
public static Singleton1_2 getInstance() {
// may get half object
if (st == null) {
synchronized (Singleton1_2.class) {
if (st == null) {
st = new Singleton1_2();
}
}
}
return st;
}
}[/code]
四: 包含模式变种3, 完美
[code lang=”java”]
/**
* 变种2的核心是DCL,看起来变种2似乎已经达到了理想的效果:懒加载+线程安全。
* 可惜的是,正如注释中所说,DCL仍然是线程不安全的,由于指令重排序,你可能会得到“半个对象”
*/</pre>
<pre> * 针对变种3的“半个对象”问题,变种3在instance上增加了volatile关键字
*/
public class Singleton1_3 {
private static volatile Singleton1_3 st = null;
private Singleton1_3() {
}
public static Singleton1_3 getInstance() {
if (st == null) {
synchronized (Singleton1_3.class) {
// must be a complete instance
if (st == null) {
st = new Singleton1_3();
}
}
}
return st;
}
}</pre>
<pre>[/code]
五:饿汉模式,天生线程安全
[code lang=”java”]
/**
* 饿汉模式
* 好处: 天生线程安全
* 坏处:资源浪费
*/
public class Singleton2 {
private static final Singleton2 singleton = new Singleton2();
private Singleton2() {
}
public static Singleton2 getInstance() {
return singleton;
}
}[/code]
六:holder模式 完美
[code lang=”java”]
/**
* 我们既希望利用饿汉模式中静态变量的方便和线程安全;又希望通过懒加载规避资源浪费。
* Holder模式满足了这两点要求:核心仍然是静态变量,足够方便和线程安全;通过静态的Holder类持有真正实例,间接实现了懒加载。
*/
public class Singleton3 {
private static class SingletonHolder {
private static final Singleton3 singleton = new Singleton3();
private SingletonHolder() {
}
}
private Singleton3() {
}
public synchronized static Singleton3 getInstance() {
return SingletonHolder.singleton;
}
}[/code]
七 枚举实现