单例模式总结

单例模式的含义

单例模式的意思就是只有一个实例。单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例

一般只有一个私有的构造方法,它可以通过调用公共的静态方法来获得这个实例

单例模式的好处

主要作用是保证在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;  
    }  
}  

  

啊啊

posted @ 2018-03-22 19:52  晋心  阅读(1614)  评论(0编辑  收藏  举报