概念
顾名思义,就是无论如何,只让生成一个实例对象的模式了。本篇主要介绍几种单例模式的写法。
懒汉式,线程不安全
最基本的实现,但最大的问题就是不支持多线程。
public class LazeM {
private static LazeM lazem;
private LazeM(){}
public static LazeM getInstance(){
if(lazem==null){
lazem = new LazeM();
}
return lazem;
}
}
懒汉式,线程安全
这种模式,相较于前一种,添加了synchronized关键字。支持多线程,但是效率比较低。
public class LazySafe {
private static LazySafe lazy;
private LazySafe(){};
public static synchronized LazySafe getInstance(){
if(lazy==null){
lazy = new LazySafe();
}
return lazy;
}
}
饿汉式、线程安全
这种模式,多线程时安全的,但是很明显,不是懒加载。
public class Lazy {
private static Lazy lazyInstance = new Lazy();
private Lazy(){};
public static Lazy getInstance(){
return lazyInstance;
}
}
双重检查锁(dcl)
这种模式,效率高,支持多线程,而且好多面试java的时候愿意问这个。
public class Dcl {
private volatile static Dcl dcl;
private Dcl(){}
public static Dcl getInstance(){
if(dcl==null){
synchronized(Dcl.class){
if(dcl==null){
dcl = new Dcl();
}
}
}
return dcl;
}
}
静态内部类
这种方式能达到双检锁方式一样的功效,但实现更简单。
public class StaticM {
private static class StaticMHolder{
private static final StaticM staticM = new StaticM();
}
private StaticM(){}
public static final StaticM getInstanc(){
return StaticMHolder.staticM;
}
}
枚举
这种方式是 Effective Java 作者 Josh Bloch 提倡的方式,它不仅能避免多线程同步问题,而且还自动支持序列化机制,防止反序列化重新创建新的对象,绝对防止多次实例化。
public enum Singleton {
INSTANCE;
public void whateverMethod() {
}
}
The End
所有的单例模式都需要把构造函数设置位private。一般情况下,建议使用饿汉式单例,如果明确需要懒加载的话,可以使用静态内部类的方式。当然,dcl也是很好用的。