Java单例模式的9种实现方式
一.饿汉式
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton (){
}
public static Singleton getInstance() {
return instance;
}
}
JDK中,java.lang.Runtime就是典型的使用饿汉式的单例模式
二.懒汉式,线程不安全
public class Singleton {
private static Singleton instance;
private Singleton (){
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
三.懒汉式,线程安全
public class Singleton {
private static Singleton instance;
private Singleton (){
}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
四.双检锁/双重校验锁(DCL,即 double-checked locking)
JDK 版本:JDK1.5 起
public class Singleton {
private volatile static Singleton singleton;
private Singleton (){
}
public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
五.静态内部类
public class Singleton {
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton (){
}
public static final Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
六.枚举
JDK 版本:JDK1.5 起
public enum Singleton {
INSTANCE;
public void whateverMethod() {
}
}
七.双检锁/双重校验锁(DCL,即 double-checked locking)(加volatile)
JDK 版本:JDK1.5 起
public class Singleton {
# 使用volatile设置内存屏障,确保线程访问资源可见性。
private volatile static Singleton singleton;
private Singleton (){
}
public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
八.使用ThreadLocal实现单例
public class Singleton {
// 用空间换时间
private static final ThreadLocal<Singleton> tl = new ThreadLocal<Singleton>();
@Override
protected Singleton initialValue() {
return new Singleton();
}
private Singleton() {
}
public static Singleton getInstance() {
return tl.get();
}
}
九.使用CAS锁实现单例
private static final AtomicReference<Singleton> INSTANCE = new AtomicReference<Singleton>();
private Singleton() {
}
public static final Singleton getInstance() {
for (; ; ) {
Singleton current = INSTANCE.get();
if (current != null) {
return current;
}
current = new Singleton();
if (INSTANCE.compareAndSet(null, current)) {
return current;
}
}
}