摘自《Header First设计模式》文中的源码
原始方法:
Singleton.java
package singleton;
public class Singleton {
//利用静态变量记录Singleton类唯一的实例
private static Singleton uniqueInstance = null;
//声明为私有的构造器,只有Singleton类内才能能够调用构造器
private Singleton() {
System.out.println("初代单例模式初始化!");
}
//用getInstance实例化对象,并返回这个实例
public static Singleton getInstance() {
if (uniqueInstance == null) {
//注意如果我们不需要这个实例,他就永远不会产生,这里采用的"延时实例化"
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
public void showMessage() {
System.out.println("Hello Singleton!");
}
}
懒汉式:
SingletonLazy.java
package singleton;
public class SingletonLazy {
private static SingletonLazy uniqueInstance;
private SingletonLazy() {
System.out.println("懒汉模式单例模式初始化");
}
//可以迫使每个线程在进入这个方法前,等候别的线程离开该方法
public static synchronized SingletonLazy getUniqueInstance() {
if (uniqueInstance == null) {
uniqueInstance = new SingletonLazy();
}
return uniqueInstance;
}
public void showMessage() {
System.out.println("Hello SingletonLazy!");
}
}
饿汉式:
SingletonStarve.java
package singleton;
public class SingletonStarve {
//静态初始化器中,创建单件,保障了线程安全
private static SingletonStarve uniqueInstance = new SingletonStarve();
private SingletonStarve() {
System.out.println("饿汉式单例初始化!");
}
public static SingletonStarve getInstance() {
return uniqueInstance;
}
public void showMessage() {
System.out.println("Hello SingletonStarve");
}
}
双检测锁式:
SingletonLazyDoubleLock.java
package singleton;
public class SingletonLazyDoubleLock {
//volatile确保当变量uniqueInstance被初始化成SingletonLazyDoubleLock实例时,多个线程正确的处理uniqueInstance变量
private volatile static SingletonLazyDoubleLock uniqueInstance;
private SingletonLazyDoubleLock() {
System.out.println("双检测锁单例初始化!");
}
public static SingletonLazyDoubleLock getInstance() {
//检查实例,如果不存在就进入同步区
if (uniqueInstance == null) {
//注意只有第一次才彻底执行这里代码
synchronized (SingletonLazyDoubleLock.class) {
//进入区块后,做第二次检查,如果为null才会创建实例
if (uniqueInstance == null) {
uniqueInstance = new SingletonLazyDoubleLock();
}
}
}
return uniqueInstance;
}
public void showMessage() {
System.out.println("Hello SingletonLazyDoubleLock");
}
}
执行验证:
RunDrive.java
public class RunDrive {
public static void main(String[] args) {
//原始单例模式
Singleton singleton = Singleton.getUniqueInstance();
singleton.showMessage();
//饿汉模式
SingletonStarve singletonStarve = SingletonStarve.getUniqueInstance();
singletonStarve.showMessage();
//懒汉模式
SingletonLazy singletonLazy = SingletonLazy.getUniqueInstance();
singletonLazy.showMessage();
//懒汉双锁模式
SingletonStarveDoubleLock singletonStarveDoubleLock = SingletonStarveDoubleLock.getUniqueInstance();
singletonStarveDoubleLock.showMessage();
}
}