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

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

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. Android为TV端助力 不需要Socket的跨进程推送消息AIDL!

    上篇介绍了跨进程实时通讯http://www.cnblogs.com/xiaoxiaing/p/5818161.html 但是他有个缺点就是服务端无法推送消息给客户端,今天这篇文章主要说的就是服务器推 ...

  2. html之css选择器学习

    相关内容: 什么是css选择器 标签选择器 类选择器 id选择器 并集选择器(分组选择器) 交集选择器 后代选择器 子标签选择器 属性选择器 相邻兄弟选择器 伪类选择器 伪元素选择器(伪对象选择器) ...

  3. LeetCode题解之Squares of a Sorted Array

    1.题目描述 2.问题分析 使用过两个计数器. 3.代码 class Solution { public: vector<int> sortedSquares(vector<int& ...

  4. java最小公倍数与最大公约数

    import java.util.Scanner; /** * Created by Admin on 2017/3/26. */ public class test02 { public stati ...

  5. c# 建立到数据源的连接 以及获取项目配置文件的属性

    两种连接数据库的写法: <connectionStrings> <add name="HRModelsContainer" connectionString=&q ...

  6. Solidity高级理论(二):Gas

    solidity高级理论(二):Gas 关键字:Gas.结构体.节省小技巧 Gas是什么 在Solidity中,用户想要执行DApp都需要支付一定量的Gas,Gas可以用以太币购买,所以,用户每次使用 ...

  7. Android 模块构建错误不能下载依赖包

    在模块的build.gradle里面添加了 implementation 'com.android.support:design:26.1.0' 构建的时候一直报这个错 Unable to resol ...

  8. 在ubuntu18.04上安装EOS

    在ubuntu18.04上安装EOS 在ubuntu18.04上安装EOS的目的: 把交易所的eos转到eos主网,防止交易所跑路或者交易所被黑客攻击 在不联网的安全环境下,用eos官方的命令行工具, ...

  9. IIS下MySQL停止和启动的方法

    mysql服务的启动与停止:点击开始--运行,输入services.msc , 在弹出的服务窗口中,找到mysql服务,直接点击左侧对应  的就可以了 如下图所示:

  10. Xlua 不同平台链接库编译

    xlua 下载包中提供lua5.3的库文件,如果需要luajit或者自己添加删除的就需要自己进行编译. Lua53版本没那么多事,主要是LuaJIt版本折腾的比较久. 工具 Xlua使用CMake进行 ...