单例模式详解

在设计模式中单例模式保证一个类中只有一个实例,并且提供一个全局访问点。

一般会用以下几种实现方式:

1、饿汉模式:

这种方式在类加载时就完成了初始化,所以类加载较慢,但获取对象的速度快。 这种方式基于类加载机制避免了多线程的同步问题,但是也不能确定有其他的方式(或者其他的静态方法)导致类装载,这时候初始化instance显然没有达到懒加载的效果。

public class Singleton {  
     private static Singleton instance = new Singleton();  
     private Singleton (){
     }
     public static Singleton getInstance() {  
     return instance;  
     }  
 }  

2、懒汉模式(线程不安全):

懒汉模式申明了一个静态对象,在用户第一次调用时初始化,虽然节约了资源,但第一次加载时需要实例化,反映稍慢一些,而且在多线程不能正常工作。

public class Singleton {  
      private static Singleton instance;  
      private Singleton (){
      }   
      public static Singleton getInstance() {  
      if (instance == null) {  
          instance = new Singleton();  
      }  
      return instance;  
      }  
 }  

3、懒汉模式(线程安全):

这种方式在类加载时就完成了初始化,所以类加载较慢,但获取对象的速度快。 这种方式基于类加载机制避免了多线程的同步问题,但是也不能确定有其他的方式(或者其他的静态方法)导致类装载,这时候初始化instance显然没有达到懒加载的效果。

public class Singleton {  
      private static Singleton instance;  
      private Singleton (){
      }
      public static synchronized Singleton getInstance() {  
      if (instance == null) {  
          instance = new Singleton();  
      }  
      return instance;  
      }  
 }  

4、双重校验锁模式:

public class singleton{
    private volatitle static singleton instance; //使用volatile 表明每次都会去内存中读取最新的值; static 表明生成周期和当前应用一样

    public singleton(){
    }

    public static singleton getInstance(){  //同样使用静态方法获取
         if(instance == null){
              synchronized (singleton.classs){ //在多线程中获取需要进行同步,或者会导致同步问题
                   if(instance == null)
                         instance = new singleton();   
              }
         }
         return instance;
    }
}

5、静态内部类

这种方式是Singleton类被装载了,instance不一定被初始化。因为SingletonHolder类没有被主动使用,只有显示通过调用getInstance方法时,才会显示装载SingletonHolder类,从而实例化instance。

public class singleton { 
    private singleton(){
    }
    public static singleton getInstance(){  
        return singletonHolder.sInstance;  
    }  
    private static class singletonHolder {  
        private static final singleton sInstance = new singleton();  
    }  
} 

6、枚举单例

默认枚举实例的创建是线程安全的,并且在任何情况下都是单例

public enum Singleton {  
     INSTANCE;  
     public void doSomeThing() {  
     }  
 }  

 

 上述讲的几种单例模式实现中,有一种情况下他们会重新创建对象,那就是反序列化,将一个单例实例对象写到磁盘再读回来,从而获得了一个实例。反序列化操作提供了readResolve方法,这个方法可以让开发人员控制对象的反序列化

 

posted on 2019-03-08 16:30  kma  阅读(113)  评论(0编辑  收藏  举报

导航