单例模式
使用工厂方法来限制实例化过程
定义:一个类有且仅有一个实例,并且自行实例化向整个系统提供。
规则:一个类只能自己创建唯一的实例;自动运行;允许系统访问
优点:避免内存多重占用;减少内存缓存
缺点:不能继承,无接口,不考虑外部如何实现实例化
关键:构造的函数必须是私有的
Java中单例模式定义:“一个类有且仅有一个实例,并且自行实例化向整个系统提供。
第一种形式:懒汉式。
public class SingletonClass{
private static SingletonClass instance=null; public static synchronized SingletonClass getInstance(){
if(instance==null){ instance=new SingletonClass();
}
return instance;
}
private SingletonClass(){
} }
第二种形式:饿汉式
对第一行static的一些解释 java允许我们在一个类里面定义静态类。比如内部类(nested class)。
把nested class封闭起来的类叫外部类。
在java中,我们不能用static修饰顶级类(top level class)。 只有内部类可以为static。
public class Singleton{
//在自己内部定义自己的一个实例,只供内部调用
private static final Singleton instance = new Singleton();
private Singleton(){
//do something
}
//这里提供了一个供外部访问本class的静态方法,可以直接访问 public static Singleton getInstance(){
return instance;
} }
--------懒汉式
//线程安全--lazy初始化
//优点:第一次调用才初始化,避免内存浪费。
//缺点:必须加锁 synchronized 才能保证单例,但加锁会影响效率。
public class Singleton {
private static Singleton instance;
private Singleton (){} public static Singleton getInstance() {
if (instance == null) { instance = new Singleton();
}
return instance;
} }
---------饿汉式
//线程安全--没有lazy初始化
//优点:没有加锁,执行效率会提高。
//缺点:类加载时就初始化,浪费内存。。
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton (){} public static Singleton getInstance() {
return instance;
} }
-----------双检锁/双重校验锁(DCL,即 double-checked locking)
//lazy初始化 线程安全
//这种方式采用双锁机制,安全且在多线程情况下能保持高性能。
这种方式采用双锁机制,安全且在多线程情况下能保持高性能。
//getInstance() 的性能对应用程序很关键。
getInstance() public class Singleton {
private volatile static Singleton singleton;
private Singleton (){} public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) { singleton = new Singleton();
} } }
return singleton;
} }
------静态内部类
public class Singleton {
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
} private Singleton (){
} public static final Singleton getInstance() {
return SingletonHolder.INSTANCE;
} }
------枚举
//线程安全--lazy初始化
//是实现单例模式的最佳方法。它更简洁,自动支持序列化机制,绝对防止多次实例化。
//不仅能避免多线程同步问题,而且还自动支持序列化机制 //防止反序列化重新创建新的对象,绝对防止多次实例化。
// JDK1.5 之后才加入 enum 特性,用这种方式让人感觉生疏,实际工作很少用。
public enum Singleton {
INSTANCE;
public void whateverMethod() {
} }