博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
如何写出一个好的单例模式
阅读量:5812 次
发布时间: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://wstbx.baihongyu.com/

你可能感兴趣的文章
matlab fread
查看>>
通过Roslyn构建自己的C#脚本(更新版)(转)
查看>>
红黑树
查看>>
mybatis08
查看>>
01 awk工具的使用
查看>>
UIImagePickerController拍照与摄像
查看>>
Maven--(一个坑)在settings.xml文件中添加mirrors导致无法新建Maven项目
查看>>
linux日志:syslogd和klogd及syslog
查看>>
Python模块学习笔记— —time与datatime
查看>>
python调用windows api
查看>>
linux添加somebody到组
查看>>
Linux内核中的printf实现【转】
查看>>
第四章 mybatis批量insert
查看>>
Dom4j生成xml
查看>>
rsync算法原理和工作流程分析
查看>>
Java并发框架——什么是AQS框架
查看>>
pthread_cleanup_push
查看>>
【数据库】
查看>>
spring框架中的@Import注解
查看>>
How to set the initial value of a select element using AngularJS ng-options & track by
查看>>