概述:单例模式这种类型属于对象创建型模式,保证一个类仅有一个实例,并提供一个访问它的全局访问点.
理解:某些类创建对象是非常复杂与时耗内存,这种类创建的对象我们称之为重量级对象。如果需要使用重量级重量级类,一般把这个类设计为单例对象模式,好处有:
1)保证对象再内存中仅有一个,减少内存开销
2)使用着不需要考虑创建细节,使用方便
懒汉式:延迟创建(调用的时候创建)、线程不安全
public class SingletonClass {
//保存唯一的实例
private static SingletonClass ONLY;
//屏蔽外部的new
private SingletonClass(){
}
//提供一个全家的访问点
public synchronized static SingletonClass getInstance(){
if(ONLY==null){
//...
ONLY=new SingletonClass();
}
//...其他代码
return ONLY;
}
public void f(){
System.out.println("hahaha");
}
}
饿汉式:立即创建、线程安全、没有延迟
public class SingletonClass {
//创建唯一的实例
private static final SingletonClass ONLY=new SingletonClass();
//屏蔽外部的new
private SingletonClass(){
}
//提供一个全家的访问点
public static SingletonClass getInstance(){
//...其他代码
return ONLY;
}
public void f(){
System.out.println("hahha");
}
}
双重验证:延迟加载、线程安全、同步情况下效率高、实现复杂
public class SingletonClass {
//保存唯一的实例
private static SingletonClass ONLY;
//屏蔽外部的new
private SingletonClass(){
}
//提供一个全家的访问点
public static SingletonClass getInstance(){
if(ONLY==null){
//B
synchronized (SingletonClass.class) {
if(ONLY==null){
//A
ONLY=new SingletonClass();
}
}
}
//...其他代码
return ONLY;
}
public void f(){
System.out.println("hahha");
}
}
类加载式:延迟加载、线程安全、同步情况下效率高、实现简单
public class SingletonClass implements Serializable,Cloneable{
//屏蔽外部的new
private SingletonClass(){
}
//静态内部类,用于持有唯一的SingletonClass的示例
private static class OnlyInstanceHolder{
static private SingletonClass ONLY=new SingletonClass();
}
//公开的唯一访问点
public static SingletonClass getInstance(){
return OnlyInstanceHolder.ONLY;
}
//自定义反序列化返回的对象
private Object readResolve() throws ObjectStreamException{
return getInstance();
}
//克隆
@Override
protected Object clone() throws CloneNotSupportedException {
return getInstance();
}
}
枚举方式:立即加载、线程安全、实现简单、防止反序列化
public enum SingletonClass {
INSTANCE;
public void f(){
System.out.println("SingletonClass.f()");
}
}
总结:一般情况下,应该使用饿汉式(第一种方式)。如果需要延迟加载,推荐使用类加载方式。如果需要非常标准的单例模式(不能new,不能被反序列化时),推荐使用枚举实现。如果单例对象在创建过程中其他特殊的需求,可以考虑使用双重验证方式。