1、饿汉式
//饿汉式单例模式
public class HungryMan {
private HungryMan(){ //私有化构造器
}
private final static HungryMan instance = new HungryMan();
public static HungryMan getInstance() {
return instance;
}
}
优点:线程安全,使用没用延迟
缺点:启动时即创建实例,启动慢,容易产生垃圾
2、懒汉式
//懒汉式单例模式
public class LazyMan {
private LazyMan(){ //私有构造方法
}
private static LazyMan instance = null;
public LazyMan getInstance(){
if (instance == null) { //需要且不存在的时候再创建实例
instance = new LazyMan();
}
return instance;
}
}
优点:懒加载启动快,资源占用小
缺点:线程不安全
3、DCL懒汉式(双重检测锁模式)
//DCL懒汉式
public class LazyMan {
private LazyMan(){ //私有构造方法
}
private volatile static LazyMan instance = null; //原子性
public LazyMan getInstance(){
if (instance == null) {
synchronized (LazyMan.class){ //加锁
if (instance == null) {
instance = new LazyMan();
}
}
}
return instance;
}
}
优点:线程安全,懒加载启动快,资源占用小
缺点:synchronized为独占排他锁,并发性能差。即使在创建成功以后,获取实例仍是串行化操作。
4、Holder模式(静态内部类)
//静态内部类懒汉式
public class Holder {
private Holder(){ //私有化构造器
}
private static class InnerClass{ //静态内部类
private static final Holder instance = new Holder();
}
public static Holder getInstance(){
return InnerClass.instance;
}
}
优点:将懒加载和线程安全完美结合的一种方式(无锁)。 (较推荐)
5、枚举单例模式
public enum Singleton {
Instance;
//可以省略此方法,通过Singleton.Instance进行操作。
public Singleton getInstance() {
return Instance;
}
}
优点:线程安全
缺点:可读性较差
总结:
枚举单例模式在《Effective Java》中推荐的单例模式之一。但枚举实例在日常开发是很少使用的,就是很简单才导致可读性较差。
在以上所有的单例模式中,推荐静态内部类单例模式。主要是非常直观,即保证线程安全又保证唯一性。