Java设计模式——单例设计模式
单例设计模式,即只造一个对象,采取一定的方法保证在整个的软件系统,对某个类只能存在一个实例对象。
1.实现方式:
1.1懒汉式,线程不安全
优势:延迟对象的创建(lazy loading),节约内存;
劣势:目前的写法,线程不安全;
class Store{
//1.私有化类的构造器
private Store(){
}
//2.声明当前类的对象,没有初始化
//4.此对象也必须声明为static
private static Store instance = null;
//3.声明public,static的返回当前对象的方法
public static Store getInstance(){
if(instance == null){
instance = new Store();//只构造一个对象
}
return instance;
}
}
1.2懒汉式,线程安全
优势:延迟对象的创建(lazy loading),节约内存,线程安全;
劣势:必须加锁 synchronized 才能保证单例,加锁效率低,绝大部分情况不需要同步;
class Store2{
private Store2(){}
private static Store2 instance;
//通过synchronized同步保证单例
public static synchronized Store2 getInstance(){
if (instance == null){
instance = new Store2();
}
return instance;
}
}
1.3饿汉式
通常情况下使用这种方式进行单例实例化
优势:线程安全
劣势:对象加载时间过长,容易产生垃圾对象,浪费内存
class Bank{
//1.私有化的构造器
private Bank(){
}
//2.内部创建类的对象
//4.要求此刻对象也必须声明为静态的
private static Bank instance = new Bank();
//3.提供公共的方法,返回类的对象
public static Bank getInstance(){
return instance;
}
}
1.4双检锁/双重校验锁(DCL, Double-Checked Locking)
优势:对象延迟加载(lazy loading),节约内存,线程安全,采用双锁机制,多线程下保持高性能;
劣势:实现较为复杂;
class Singleton{
private Singleton(){};
private volatile static Singleton instance;
public static Singleton getInstance(){
if (instance == null){
synchronized (Singleton.class){
if(instance == null){
instance = new Singleton();
}
}
}
return instance;
}
}
1.5登记式/静态内部类
通过对静态域使用延迟初始化,实现更简单,但只适合静态域的情况。双检锁方式可在实例需要延迟初始化时使用。
优势:对象延迟加载(lazy loading),节约内存,线程安全;
劣势:只适用于静态域;
class Singleton2{
private Singleton2(){};
//类被加载时,instance没有被实例化,
// 只有调用getInstance才会显式加载SingletonHolder类,从而实例化instance
private static class SingletonHolder{
private static final Singleton2 instance = new Singleton2();
}
public static final Singleton2 getInstance(){
return SingletonHolder.instance;
}
}
1.6枚举
Effective Java 作者 Josh Bloch提倡的方式,能避免多线程同步问题,还自动支持序列化机制,防止反序列化重新创建新的对象,绝对防止多次实例化。jdk1.5之后加入enum特性。实际工作中,目前用的比较少。
优势:线程安全,实现容易;
劣势:对象直接加载;
//枚举类,一般表示一组常量
enum Singleton3{
INSTANCE;
public void whateverMethod(){
}
}