• 单例模式


    单例模式可以说是最常见而短小的设计模式,这也让它经常在面试中被问到。

    单例模式就是某个类只能生成一个对象。主要应有于某些确实只需要一个对象的情况,比如线程池。

    首先第一步当然是使用private修饰构造方法,这样别人地方就不能用new来新建一个对象。然后在代码中添加一个静态方法,这个方法可以返回一个实例对象。那么怎么控制这个方法只能返回一个对象呢?可以在类里面声明一个以这个类为静态类型的static字段instance。这样每次调用这个方法的时候就检查这个字段是不是null,是的话就new一个并且返回,不是的话就直接返回instance(已经被新建过了)。

    但是如果单纯这样只适用于单线程的情况下,在实际应用中要考虑多线程的情况:A线程判断instance为null就准备新建,可是还没有新建成功返回对象的引用的时候发生了线程调度,B线程也因为这个instance是null而准备开始新建。结果就是产生了两个对象。

    那么在这里需要做的是使这个设计模式线程安全。

    方法有3:

    1,使用synchronized修饰这个方法使其自动加锁实现互斥进入。问题是效率低,如果大量被使用这个方法,会有很大开销,同时只有第一次是真正需要加锁的,但这里以后每一次都有一个没意义的加锁过程。当然这么做也是解决问题的一种方式,如果确实调用很少也不是不可以用。

    2,直接在类的属性声明中新建一个。比如这么写:

    1 private static SingletonClass instance = new SingletonClass();

    这样做的话在JVM加载这个类的时候就会由<clinit>方法自动给他创建一个,以后连对它是否为null的判断都不用了。但是问题也很明显,这样做的话无法在真正需要的时候再新建对象,如果这个对象很大,那么它过长的生命周期会给JVM的堆带来不必要的开销。

    3,双重检查模式

     1 class Singleton {
     2 
     3     private volatile static Singleton instance;
     4 
     5     private Singleton() {
     6 
     7     }
     8 
     9     public static Singleton getInstance() {
    10         if (instance == null) {
    11             synchronized (Singleton.class) {
    12                 if (instance == null) {
    13                     return new Singleton();
    14                 }
    15             }
    16         }
    17         return instance;
    18     }
    19 }

    为什么要两个if判断?第一个if的主要作用是分流,换句话说,在第一次创建之后,很多的调用可以因为这个if直接被pass掉,根本不进入同步代码块,也就减少了不必要的同步的开销。第二个if是保证这个设计模式逻辑成立的关键。如果没有第二个if,可能发生这种情况:线程A因为instance为null进入了代码块,但是发生了线程调度,线程B也随之进入代码块(这个时候instance还是null)。也许有人会问,这个地方不是用synchronized括起来的吗?怎么线程B还能进入?注意synchronized的部分从来不是不准进入而是进入后会阻塞(如果已经有线程进入了的话)。这样接下来线程B阻塞在这里面,等线程A新建了对象之后,如果没有第二个if就会让线程B也新建一个对象。

  • 相关阅读:
    Nginx 性能优化有这篇就够了!
    Zabbix Web API Get方法整合
    MySQL利用binlog恢复误操作数据(python脚本)
    Tomcat7 1000并发量配置以及配置优化
    MySQL中 如何查询表名中包含某字段的表
    python异步编程之asyncio(百万并发)
    微信支付开发(7) 刷卡支付
    <Android 基础(二十)> CoordinatorLayout Behavior
    实例解析Docker数据卷+数据卷容器+flocker数据共享+DockerHub操作
    我和滴滴打车司机的那些事
  • 原文地址:https://www.cnblogs.com/dsj2016/p/5702668.html
Copyright © 2020-2023  润新知