zoukankan      html  css  js  c++  java
  • 设计模式随笔之——单列模式

    一、单例模式的定义:

      单例模式是一个比较简单的模式,其定义为:确保某一个类只有一个实例,而且自行实例化并像整个系统提供这个实例。单例模式大致可以分为:饿汉式和懒汉式。

      以下关于单例模式的优点、缺点、使用场景摘自《设计模式之禅》

    二、单例模式的优点:

      1、由于单例模式在内存中只有一个实例,减少了内存开支,特别是一个对象需要频繁的创建、销毁,而且创建或销毁时性能无法优化,单例模式的优势就更加明显。

      2、由于单例模式只生成一个实例,所以减少了系统性能开销,当一个对象产生需要较多资源时,如读取配置、产生其它依赖对象时,则可以通过在应用启动时直接产生一个单例对象,然后用永久驻留内存的方式来解决(Java EE中采用单例模式需要注意JVM的垃圾回收机制)

      3、单例模式可以避免对资源的多重占用,例如一个文件写入动作,由于只有一个实例存在,避免对同一个资源文件的同时写操作。

      4、单例模式可以在系统设置全局访问点,优化和共享资源访问,例如可以设计一个单例类,负责所有数据表的映射处理

    三、单例模式的缺点:

      1、单例模式一般没有接口,扩展困难,若要扩展,除了修改代码基本没有第二张途径。单例模式为什么不能增加接口呢?因为接口对单例模式是没有任何意义,它要求“自行实例化”,并且提供单一实例、接口或抽象类是不可能被实例化的。当然,在特殊情况下,单例模式可以实现接口、被继承等,需要在系统开发中根据环境判断。

      2、单例模式对测试是不利的。在并行开发环境中,如果单例模式没有完成,是不能进行测试的,没有接口也不能使用mock的方式虚拟一个对象

      3、单例模式与单一职责原则冲突。一个类应该只实现一个逻辑,而不关心它是否是单例的,是不是单例要取决于环境,单例模式把“要单例”和业务逻辑融合在一个类中。

    四、单例模式的使用场景:

      在一个系统中,要求一个类有且仅有一个对象,如果出现多个对象就会出现“不良反应”,可以采用单例模式

      1、要求生成唯一序列号的环境

      2、在整个项目中需要一个共享访问点或共享数据,例如一个web页面上的计数器,可以不用把每次刷新都记录到数据库中,使用单例模式保持计数器的值,并确保是线程安全的

      3、创建一个对象需要小号的资源过多,如访问IO和数据库等资源

      4、需要定义大量的静态常量和静态方法(如工具类)的环境,可以采用单例模式(当然,也可以直接声明为static的方式)

    五、饿汉式、懒汉式单例模式:

      1、饿汉式单例模式

     1 /**
     2  * 饿汉式单例模式,在类加载时就已经创建一个单例
     3  * 
     4  * @author Lion
     5  * 
     6  */
     7 public class Singleton {
     8 
     9     // 私有静态实例变量,在类加载时就已经创建完成
    10     private static Singleton singleton = new Singleton();
    11 
    12     // 私有构造函数,保证不在类外部被访问
    13     private Singleton() {
    14     }
    15 
    16     // 公开的静态方法返回一个Singleton实例
    17     public static Singleton getInstance() {
    18         return singleton;
    19     }
    20 
    21     public static void main(String[] args) {
    22         // 输出,测试是否为同一个对象
    23         for (int i = 0; i < 3; i++) {
    24             System.out.println(Singleton.getInstance().toString());
    25         }
    26     }
    27 }

      2、懒汉式单例模式

     1 /**
     2  * 懒汉式单例模式,只在第一次请求时创建一个实例,以后不在创建实例 但会出现线程不安全
     3  * 
     4  * @author Lion
     5  * 
     6  */
     7 public class Singleton1 {
     8 
     9     // 私有静态实例变量
    10     private static Singleton1 singleton = null;
    11 
    12     // 私有构造方法
    13     private Singleton1() {
    14     }
    15 
    16     // 公开的静态工厂方法,返回该类的唯一实例(当发现没有实例没有初始化的时候才初始化)
    17     public static Singleton1 getInstance() {
    18         /**
    19          * <pre>
    20          * 线程不安全说明:
    21          * 如果一个线程A执行到singleton = new Singleton1(),但还没有获得对象(正在初始化);
    22          * 此时,线程B也执行到singleton == null,那么线程B的判断条件也为真,于是执行了singleton = new Singleton1();
    23          * 最终,线程A获得了一个对象,线程B也获得了一个对象,故内存中就出现了两个对象
    24          * </pre>
    25          */
    26         if (singleton == null) {
    27             singleton = new Singleton1();
    28         }
    29         return singleton;
    30     }
    31 
    32     public static void main(String[] args) {
    33         System.out.println("没什么好测试的,线程安全只会出现在大量并发的情况下,低并发与饿汉模式一样");
    34     }
    35 }

      嗯,单例模式以我现在理解就这么点内容,如果有新的理解会补充的

    作者:登天路

    转载请说明出处:http://www.cnblogs.com/travellife/

  • 相关阅读:
    【Hadoop学习之七】Hadoop YARN
    【Hadoop学习之六】MapReduce原理
    【Hadoop学习之五】win7+Eclipse+hadoop3搭建本机开发环境
    【Hadoop学习之四】HDFS HA搭建(QJM)
    【Hadoop学习之三】Hadoop全分布式安装
    【Hadoop学习之二】Hadoop伪分布式安装
    【Hadoop学习之一】Hadoop介绍
    【Linux学习十】负载均衡带来tomcat的session不一致问题
    【Linux学习九】负载均衡
    Okhttp3基本使用
  • 原文地址:https://www.cnblogs.com/travellife/p/4073356.html
Copyright © 2011-2022 走看看