单例模式总结
单例模式的含义
单例模式的意思就是只有一个实例。单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
一般只有一个私有的构造方法,它可以通过调用公共的静态方法来获得这个实例。
单例模式的好处
主要作用是保证在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; } }
啊
啊啊
坚持不懈