设计模式--单例模式

单例模式是设计模式中最简单的形式之一。这一模式的目的是使得类的一个对象成为系统中的唯一实例。要实现这一点,可以从客户端对其进行实例化开始。因此需要用一种只允许生成对象类的唯一实例的机制,“阻止”所有想要生成对象的访问。使用工厂方法来限制实例化过程。这个方法应该是静态方法(类方法),因为让类的实例去生成另一个唯一实例毫无意义。

1.饿汉式,线程安全 但效率比较低

  • 优点是:写起来比较简单,而且不存在多线程同步问题,避免了synchronized所造成的性能问题;

  • 缺点是:当类SingletonTest被加载的时候,会初始化static的instance,静态变量被创建并分配内存空间,从这以后,这个static的instance对象便一直占着这段内存(即便你还没有用到这个实例),当类被卸载时,静态变量被摧毁,并释放所占有的内存,因此在某些特定条件下会耗费内存。

     public class HungrySingleton {
    
         //定义一个私有构造方法
         private HungrySingleton(){
     
         }
     
         //将自身的实力对象设置为一个属性,并加上Static和final修饰符
         private static final HungrySingleton instance = new HungrySingleton();
     
         //静态方法返回该类的实例
         public static HungrySingleton getInstance(){
             return instance;
         }
     }
    

2.饱汉式,非线程安全

  • 优点是:写起来比较简单,当类SingletonTest被加载的时候,静态变量static的instance未被创建并分配内存空间,当getInstance方法第一次被调用时,初始化instance变量,并分配内存,因此在某些特定条件下会节约了内存;

  • 缺点是:并发环境下很可能出现多个SingletonTest实例。

      public class SatietySingleton {
    
          //定义私有构造方法(防止通过new SatietySingleton()去实例化
          private SatietySingleton() {
          }
      
          //定义一个SatietySingleton类型的变量(不初始化,注意这里没有使用final关键字)
          private static SatietySingleton instance;
      
          //定义一个静态的方法(调用时再初始化SatietySingleton,但是多线程访问时,可能造成重复初始化问题)
      	//[考虑线程安全时,将synchronized放开]
          public  static /**synchronized*/ SatietySingleton getInstance(){
              if (instance == null){
                  instance = new SatietySingleton();
              }
              return instance;
          }
      }
    

3.最优方案(线程安全,且效率最高)

public class BestSingleton {

    //定义一个私有构造方法
    private BestSingleton(){
    }

    //定义一个静态私有变量(不初始化,不使用final关键字,使用volatitle保证了多线程访问时instance变量的可见性,
    //避免instance初始化时其他变量属性还没赋值完事,被另外的线程调用
    private static volatile BestSingleton instance;

    //定义一个共有的静态方法,返回该类型实例
    public static BestSingleton getInstance(){
        //对象实例化时与否判断(不实用同步代码块,instance不等于null时,直接返回对象,提高运行效率
        if (instance == null){
            //同步代码块(对象未初始化时,使用同步代码块,保证多线程访问时对象在第一次创建后,不再重复被创建
            synchronized(BestSingleton.class){
                //未初始化,则初始instance变量
                if (instance == null){
                    instance = new BestSingleton();
                }
            }
        }
        return instance;
    }
}

博客链接:https://qiuxx404.github.io/2018/06/13/原创/设计模式/设计模式-单例模式

posted @ 2018-06-14 23:34  qiuxx404  阅读(60)  评论(0编辑  收藏  举报