单例模式的含义
单例模式的意思就是只有一个实例。单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
一般只有一个私有的构造方法,它可以通过调用公共的静态方法来获得这个实例。
单例模式的好处
主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。
使用Singleton的好处还在于可以节省内存,因为它限制了实例的个数,有利于Java垃圾回收
单例模式特点
1、单例类只能有一个实例。
2、单例类必须自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。
单例模式的选型:
在实现层面上,目前的几种主要的单例模式往往有以下几项性能指标作为选型参考:
-- 是否实现延迟加载
-- 是否线程安全
-- 并发访问性能
-- 是否可以防止反射与反序列化穿透
一个线程访问一个对象中的synchronized(this)同步代码块时,其他试图访问该对象的线程将被阻塞。
1.懒汉式单例
在类加载的时候不创建单例实例。只有在第一次请求实例的时候的时候创建,并且只在第一次创建后,以后不再创建该类的实例。
懒汉式如果在创建实例对象时不加上synchronized则会导致对对象的访问不是线程安全的
//单例模式-懒汉式单例
public class LazySingleton {
//私有静态对象,加载时候不做初始化
private static LazySingleton m_intance=null;
// 私有构造方法,避免外部创建实例
private LazySingleton(){}
/**
* 静态工厂方法,返回此类的唯一实例.
* 当发现实例没有初始化的时候,才初始化.
*/
synchronized public static LazySingleton getInstance(){
if(m_intance==null){
m_intance=new LazySingleton();
}
return m_intance;
}
}
2. 饿汉式单例
在类加载的时候就创建实例,,在类创建的同时就已经创建好一个静态的对象供系统使用
/*
* 单例模式-饿汉式单例
*/
public class EagerSingleton {
/*
* 私有的(private)唯一(static final)实例成员,在类加载的时候就创建好了单例对象
*/
private static final EagerSingleton m_instance = new EagerSingleton();
/**
* 私有构造方法,避免外部创建实例
*/
private EagerSingleton() {
}
/**
* 静态工厂方法,返回此类的唯一实例.
* @return EagerSingleton
*/
public static EagerSingleton getInstance() {
return m_instance;
}
}
3. 登记式单例
这个单例实际上维护的是一组单例类的实例,将这些实例存放在一个HashTable(登记薄)中,对于已经登记过的实例,则从工厂直接返回,对于没有登记的,则先登记,而后返回。
//用来存储单例(StringManager)的变量的hash类
private static HashTable managers = new HashTable();
//下面用关键字synchronized避免多线程时出错。
public synchronized static StringManager getManager(String packageName){
StringManager mgr = (StringManager)managers.get(packageName);
if(mgr == null){
mgr = new StringManager(packageName);
managers.put(packageName,mgr);
}
return mgr;
}
4.双重锁定单例(改进懒汉式)
考虑这样一种情况,就是有两个线程同时到达,即同时调用 getInstance() 方法。两个线程都会创建一个实例,这就违背了单例模式的初衷。因此加双重锁定
public class Singleton {
private static volatile Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
啊
啊啊