avatar

目录
单例设计模式

为什么要用单例模式?手写几种线程安全的单例模式?

简单来说使用单例模式可以带来下面几个好处:

  • 对于频繁使用的对象,可以省略创建对象所花费的时间,这对于那些重量级对象而言,是非常可观的一笔系统开销;
  • 由于 new 操作的次数减少,因而对系统内存的使用频率也会降低,这将减轻 GC 压力,缩短 GC 停顿时间。

单例模式有多种实现方式,但是,有三个相同的特点:

  • 构造器私有;
  • 含持有自己类型的属性;
  • 对外提供获取实例的静态方法;

懒汉式(双重检查加锁版本)

public class Singleton {

    //通过将instance声明为volatile型来防止new Instance()的重排序
    private volatile static Singleton uniqueInstance;
    private Singleton() {
    }
    public static Singleton getInstance() {
       //检查实例,如果不存在,就进入同步代码块
        if (uniqueInstance == null) {
            //只有第一次才彻底执行这里的代码
            synchronized(Singleton.class) {
               //进入同步代码块后,再检查一次,如果仍是null,才创建实例
                if (uniqueInstance == null) {
                    uniqueInstance = new Singleton();
                }
            }
        }
        return uniqueInstance;
    }
}

静态内部类方式

静态内部实现的单例是懒加载的且线程安全。

只有通过显式调用 getInstance 方法时,才会显式装载 SingletonHolder 类,从而实例化 instance(只有第一次使用这个单例的实例的时候才加载,同时不会有线程安全问题)。

public class Singleton {
    private static class SingletonHolder {
    private static final Singleton INSTANCE = new Singleton();
    }
    private Singleton (){}
    public static final Singleton getInstance() {
    return SingletonHolder.INSTANCE;
    }
}

[exocr@iz8vb85pir06gf268taw08z bin]$ ./zkServer.sh start
JMX enabled by default
Using config: /home/exocr/zookeeper-3.4.6/bin/../conf/zoo.cfg
Starting zookeeper … /bin/echo: 写入错误: 设备上没有空间
FAILED TO WRITE PID

> zookeeper.out

文章作者: 简凡丶
文章链接: http://yoursite.com/2020/01/15/8.%20%E7%AE%97%E6%B3%95-%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E5%8D%95%E4%BE%8B%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 BestBear

评论