一.懒汉式(安全版)
/**
* 单例模式(懒汉模式安全版):安全,加重量级锁效率低,实现懒加载
* @author hwyou
*
*/
public class Singleton {
private static Singleton singleton;
private Singleton(){}
public synchronized static Singleton getInstance() {
if(singleton == null) {
singleton = new Singleton();
}
return singleton;
}
}
二.饿汉式
/**
* 单例模式:饿汉式,没加锁,保证线程安全,效率高,没实现懒加载,可能会产生垃圾
* @author hwyou
*
*/
public class Singleton {
private static Singleton singleton = new Singleton();
private Singleton(){}
public static Singleton getInstance() {
return singleton;
}
}
三.双重校验锁
/**
* 单例模式:双重校验(两次判空),懒加载,加锁效率也高
* @author hwyou
*
*/
public class Singleton {
private volatile static Singleton singleton;
private Singleton(){}
public static Singleton getInstance() {
if(singleton == null) { //single check,逻辑可去,去了影响效率
synchronized (Singleton.class) {
if(singleton == null) { //不可去,可能会出现a进a退,b进,new了两次
singleton = new Singleton(); //这步不是原子操作,1.给对象分配内存2.调构造初始化3.对象指向分配的内存,所以之前加voliate
}
}
}
return singleton;
}
}
四.静态内部类(在内部类创建对象)
public class Singleton {
public static class getInstanceHandler{
private static final Singleton single = new Singleton();
}
private Singleton(){}
public static final Singleton getInstance() {
return getInstanceHandler.single;
}
}
五.枚举(防止反序列化创建对象)
public enum Singleton {
INSTANCE;
public void WhateverMethod(){
}
}
什么场景下用什么
一般情况下,不建议使用第懒汉方式,
建议使用第 2 种饿汉方式。
只有在要明确实现 lazy loading 效果时,才会使用第 4 种静态内部类。
如果涉及到反序列化创建对象时,可以尝试使用第 枚举方式。
如果有其他特殊的需求,可以考虑使用第 双检锁方式。