博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
如何写出一个好的单例模式
阅读量:5745 次
发布时间:2019-06-18

本文共 2040 字,大约阅读时间需要 6 分钟。

单例模式是设计模式中总容易理解,并且使用次数比较多的模式,往往在面试中会被问到。在这里我简述下自己的思路。希望能对你有所帮助。 ###懒汉式 单例模式

public class Single {    private static Single instance;    private Single () {}        public static Single getInstance () {      if (instance == null) {        instance = new Single();    }  return instance;  }}复制代码

上面这种,是我们众所周知的,往往教科书上也是这么写的,但是这种是线程不安全的,那么我们来看下一个。

懒汉式2

public static synchronized Single getInstance() {  if (instance == null) {    instance = new Single();   }return instance;}复制代码

这种相对第一种来说,就安全了很多,但是它并不高效。

双重检验锁

双重检验锁模式(double checked locking pattern),是一种使用同步块加锁的方法。被称其双重检验锁。是因为会有两次检验instance == null,一次是在同步块外,一次是在同步块内。

public static Single getInstance () {  if(instance == null) {    synchronized (Single.class) {      if(instance ==null) {        instance = new Single();      }    }   }  return instance;}复制代码

这样是不是很完美了,可是还有问题,我们来看下 JVM 对instance = new Single()这句话做了什么

  • 大概做了三件事: 1.给instance分配内存 2.调用Single的构造函数来初始化成员变量 3.将instance对象指向给分配的内存 JVM的即时编译器中存在指令重排序的优化。这样就会导致上边的第二步和第三步的实行顺序不确定。最终的执行顺序可能是 1-2-3 也可能是 1-3-2。如果是后者,则在 3 执行完毕、2 未执行之前,被线程二抢占了,这时 instance 已经是非 null 了(但却没有初始化),所以线程二会直接返回 instance,然后使用,然后顺理成章地报错。
public class Single() {   private volatile static Single instance; // 声明成 volatile   private Single () {}   public static Single getInstance () {     if (instance == null) {       synchronized (Single.class) {           if(instance == null) {             instance = new Single();           }       }     }     return instance;   }}复制代码

饿汉式 static final field

public class Single{    //类加载时就初始化    private static final Single instance = new Single();        private Single(){}    public static Single getInstance(){        return instance;    }}复制代码

静态内部类 static nested class

public class Single {      private static class SingleHolder {          private static final Single INSTANCE = new Single();      }      private Single (){}      public static final Single getInstance() {          return SingleHolder.INSTANCE;     }  }复制代码

枚举 Enum

用枚举写单例实在太简单了!这也是它最大的优点。下面这段代码就是声明枚举实例的通常做法。

public enum EasySingle{    INSTANCE;}复制代码

转载地址:http://viazx.baihongyu.com/

你可能感兴趣的文章
阿花宝宝 Java 笔记 之 初识java
查看>>
7、设计模式-创建型模式-建造者模式
查看>>
我国古代的勾股定理
查看>>
Linux下的C编程实战
查看>>
[32期] html中部分代码与英语单词关系
查看>>
PHP安装环境,服务器不支持curl_exec的解决办法
查看>>
jQuery|元素遍历
查看>>
RedHat 6 安装配置Apache 2.2
查看>>
Openstack 安装部署指南翻译系列 之 Manila服务安装(Share Storage)
查看>>
underscore.js学习笔记
查看>>
windows下常用命令
查看>>
1.5编程基础之循环控制_29:数字反转
查看>>
组策略 之 设备安装设置
查看>>
人工智能还能干这些?这8种AI应用你可能意想不到
查看>>
实现Hyper-V 虚拟机在不同架构的处理器间迁移
查看>>
简单使用saltstack
查看>>
针对web服务器容灾自动切换方案
查看>>
突破媒体转码效率壁垒 阿里云首推倍速转码
查看>>
容器存储中那些潜在的挑战和机遇
查看>>
R语言的三种聚类方法
查看>>