常见安全的单例实现代码和自己的一点理解。

一、 饿汉模式(静态初始化)

class Singleton{

    private Singleton(){
} private static Singleton cache=new Singleton(); public static Singleton getInstance(){
return Internal.cache;
}
}

实现最为简单,但是如果Singleton的任何一个静态字段(非常量,常量是被动引用,在编译时通过常量传播优化,放入常量池,转化为了对常量池的引用)或者静态方法被调用则会初始化。线程安全有虚拟机的保证,对象的实例化是在类加载的初始化阶段。初始化的时机详见:深入理解java虚拟机p210

二、双重检查锁(dcl)

class Singleton{

    private Singleton(){
} private volatile static Singleton cache; public static Singleton getInstance(){
if(cache==null){
synchronized (Singleton.class){
if(cache==null){
cache=new Singleton();
}
}
}
return cache;
}
}

双重检查锁是为了解决资源初始化较慢或者资源较重的场景下延迟初始化,利用synchronized关键字保证线程安全。饿汉模式是利用虚拟机本身保证类加载的的线程安全性。但是dcl本身每次都需要检查该对象是否实例化,所以引出下面的模式

三、 延迟占位类

class Singleton{

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

延迟占位类结合前两种的优势,消除了同步并且实现了延迟初始化。延迟占位类模式的线程安全也是由虚拟机来保证的,这里需要理解的是为什么能延迟初始化。相比于饿汉模式,延迟占位类模式可以实现调用getInstance方法才去初始化该类

四、枚举实现

effective java中的推荐做法。我找了一个jdk中的实现如下:

   enum NaturalOrderComparator implements Comparator<Comparable<Object>> {
INSTANCE; @Override
public int compare(Comparable<Object> c1, Comparable<Object> c2) {
return c1.compareTo(c2);
} @Override
public Comparator<Comparable<Object>> reversed() {
return Comparator.reverseOrder();
}
}

枚举本身更加安全,虚拟机层面阻止了通过反射去实例化一个类导致单例破坏的场景。

最后

此外还有懒汉模式(线程不安全)和懒汉模式直接加synchronized(性能问题)的,这种代码比较简单,实际也没使用的意义就不展开了。

java单例模式总结的更多相关文章

  1. 用java单例模式实现面板切换

    1.首先介绍一下什么是单例模式: java单例模式是一种常见的设计模式,那么我们先看看懒汉模式: public class Singleton_ { //设为私有方法,防止被外部类引用或实例 priv ...

  2. 【深入】java 单例模式(转)

    [深入]java 单例模式 关于单例模式的文章,其实网上早就已经泛滥了.但一个小小的单例,里面却是有着许多的变化.网上的文章大多也是提到了其中的一个或几个点,很少有比较全面且脉络清晰的文章,于是,我便 ...

  3. 深入Java单例模式(转)

    深入Java单例模式 源自 http://devbean.blog.51cto.com/448512/203501 在GoF的23种设计模式中,单例模式是比较简单的一种.然而,有时候越是简单的东西越容 ...

  4. Java 单例模式的七种写法

    Java 单例模式的七种写法 第一种(懒汉,线程不安全) public class Singleton { private static Singleton instance; private Sin ...

  5. java单例模式之懒汉式分析

    转自:http://blog.csdn.net/withiter/article/details/8140338 今天中午闲着没事,就随便写点关于Java单例模式的.其实单例模式实现有很多方法,这里我 ...

  6. Java 单例模式探讨

    以下是我再次研究单例(Java 单例模式缺点)时在网上收集的资料,相信你们看完就对单例完全掌握了 Java单例模式应该是看起来以及用起来简单的一种设计模式,但是就实现方式以及原理来说,也并不浅显哦. ...

  7. 单例模式:Java单例模式的几种写法及它们的优缺点

    总结下Java单例模式的几种写法: 1. 饿汉式 public class Singleton { private static Singleton instance = new Singleton( ...

  8. 9种Java单例模式详解(推荐)

    单例模式的特点 一个类只允许产生一个实例化对象. 单例类构造方法私有化,不允许外部创建对象. 单例类向外提供静态方法,调用方法返回内部创建的实例化对象.  懒汉式(线程不安全) 其主要表现在单例类在外 ...

  9. 你真的理解了java单例模式吗?讲别人都忽略的细节!

    前言:老刘这篇文章敢做保证,java的单例模式讲的比大多数的技术博客都要好,讲述别人技术博客都没有的细节!!! 1 java单例模式 直接讲实现单例模式的两种方法:懒汉式和饿汉式,单例模式的概念自己上 ...

  10. Java 单例模式详解

    概念: java中单例模式是一种常见的设计模式,单例模式分三种:懒汉式单例.饿汉式单例.登记式单例三种. 单例模式有一下特点: 1.单例类只能有一个实例. 2.单例类必须自己自己创建自己的唯一实例. ...

随机推荐

  1. Linux swappiness参数设置与内存交换

    swappiness参数设置与内存交换 by:授客 QQ:1033553122 简介 swappiness,Linux内核参数,控制换出运行时内存的相对权重.swappiness参数值可设置范围在0到 ...

  2. Kotlin入门(25)共享参数模板

    共享参数SharedPreferences是Android最简单的数据存储方式,常用于存取“Key-Value”键值对数据.在使用共享参数之前,要先调用getSharedPreferences方法声明 ...

  3. (python)排序算法

    一.冒泡排序 1.冒泡排序实现思路 需要两层循环,外层循环控制总共循环几次,内层循环控制交换的次数(注意索引超界的问题). 外层第一次循环,内层第一次循环,将第一个元素(y)与第二个元素(y+1)进行 ...

  4. SQL中的ALL,ANY,SOME的用法

    准备两个表: --T1(2,3)--T2(1,2,3,4) --ALL,ANY,SOME 的子查询-- >ALL 父查询中的结果集大于子查询中每一个结果集中的值,则为真SELECT * FROM ...

  5. Docker 入门到实践(三)Docker 安装

    注意:不要在没有配置 Docker APT 源的情况下直接使用 apt 命令安装 Docker. 一.准备工作 系统要求 Docker CE 支持一下版本的 Ubuntu 操作系统 Cosmic 18 ...

  6. 团队作业——Alpha冲刺

    团队作业--Alpha冲刺 时间安排及内容要求 时间 内容 11.1-11.16 12次 Scrum 11.16-11.20 测试报告 与 用户反馈 11.21-11.24 展示博客 11.25 课堂 ...

  7. Maven将中央仓库修改为阿里云的仓库地址

    <mirror> <id>nexus-aliyun</id> <mirrorOf>*</mirrorOf> <name>Nexu ...

  8. 解决VS Code使用code runner开发Python乱码问题

    微软开发的VS Code是一个跨平台的文本编辑器,通过各种插件,可以把自己武装成无所不能的IDE. 刚刚安装完VS Code时,迫不急待地安装了C/C++.Python以及Code Runner插件, ...

  9. Spring batch

    学习了解 https://www.ibm.com/developerworks/cn/java/j-lo-springbatch1/index.html?ca=drs-#ibm-pcon

  10. 微信小程序PHP 微信支付接口调用

    小程序端 /** * 微信支付接口 */ wxPaymoney:function (out_trade_no, true_money){ //out_trade_no 后台统一下单接口需要用 var ...