概念:

  单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式。

核心作用:

  保证一个类只有一个实例,并且提供一个访问访问该实例的全局访问点。

单例模式优点:

  单例模式只生成一个实例,减少了内存的开销,当一个对象的产生需要比较多的资源时,如读取配置,则可以通过在应用启动时直接产生一个单例对象,然后永久驻留内存的方式解决。

实现方式:

1)饿汉式/** * 优点:线程安全、调用效率高  缺点:不能延时加载 */public class  HungrySingleton {    private HungrySingleton() {    }

    private static HungrySingleton instance = new HungrySingleton(); //类初始化立即加载这个对象,天然线程安全

    public static HungrySingleton getInstance() {        return instance;    }}

要点:饿汉式单例代码中,static变量会在类加载时初始化,此时也不会涉及多个线程访问该对象的问题。而且JVM保证只会加载一次该类,肯定不会发生并发访问的问题,所以是线程安全的。问题:如果getInstance()一直没有被调用,则会造成资源浪费!

2)懒汉式/** * 优点:线程安全,能延时加载  缺点:每次调用getInstance()都要同步,并发效率低 */public class LazySingleton {    private LazySingleton() {    }    private static LazySingleton instance = null;

    public static synchronized LazySingleton getInstance() {        if (instance == null) {            instance = new LazySingleton();        }        return instance;    }}

要点:延迟加载 or 懒加载!真正用的时候才加载!问题:资源利用率高了,但是每次调用getInstance()时都要同步,并发效率较低。

3)双重检测锁式/** * 优点:线程安全,能延时加载,执行效率高(只在第一次时加锁) * 问题:由于编译器优化原因(指令重排序) 和JVM底层内部模型原因,偶尔会出问题 * 解决:可以通过在instance前面加上volatile修饰,禁止重排序 */public class DoubleCheckSingleton {    private DoubleCheckSingleton() {    }

    //private static DoubleCheckSingleton instance = null;        //由于编译器优化原因(指令重排序) 和JVM底层内部模型原因,偶尔会出问题    private volatile static DoubleCheckSingleton instance = null; //通过添加volatile修饰,可以禁止JVM优化重排序等

    public static DoubleCheckSingleton getInstance() {        if (instance == null) {synchronized (DoubleCheckSingleton.class) {                if (instance == null) {                    instance = new DoubleCheckSingleton();                }            }        }        return instance;    }}

要点:该模式将同步内容下放到了if内部,锁的范围变小,不必每次获取对象时都进行同步,只有第一次才同步,提高了执行的效率。问题:由于编译器优化原因(指令重排序) 和JVM底层内部模型原因,偶尔会出问题。可以通过添加volatile修饰解决。

4)静态内部类实现方式/** * 优点:线程安全、调用效率高、能延时加载 */public class StaticInnerClassSingleton {    private StaticInnerClassSingleton() {    }

    //只有真正调用getInstance(),才会加载静态内部类,进而实现了懒加载    private static class Singleton {        //final static保证了内存中只有这样一个实例存在,而且只能被赋值一次,从而保证线程安全        private final static StaticInnerClassSingleton instance = new StaticInnerClassSingleton();    }

    public static StaticInnerClassSingleton getInstance() {        return Singleton.instance;    }}要点:兼备了并发高效和延时加载的优势

但是,以上四种线程安全的实现方式都有一个共同的缺点,就是可以利用反射或者反序列化来重复构建对象。

5)枚举方式实现/** * 优点:枚举本身就是单例模式,线程安全、调用效率高、可以避免反射和反序列化的漏洞  缺点:没有懒加载 */public enum Singleton {    INSTANCE;    Singleton() {    }}

如何选用? * 单例对象 占用 资源少, 不需要 延时加载:枚举式 好于 饿汉式 * 单例对象 占用 资源多, 需要 延时加载:静态内部类式 好于 懒汉式

转载于:https://www.cnblogs.com/jackspan/p/9504957.html

单例模式实现方式详解相关推荐

  1. 【python教程入门学习】Python函数定义及传参方式详解(4种)

    这篇文章主要介绍了Python函数定义及传参方式详解(4种),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 一.函数初识 1.定 ...

  2. php中 继承中的概念,JavaScript_JavaScript中的继承方式详解,js继承的概念 js里常用的如下 - phpStudy...

    JavaScript中的继承方式详解 js继承的概念 js里常用的如下两种继承方式: 原型链继承(对象间的继承) 类式继承(构造函数间的继承) 由于js不像java那样是真正面向对象的语言,js是基于 ...

  3. SSO单点登录三种情况的实现方式详解

    SSO单点登录三种情况的实现方式详解 单点登录(SSO--Single Sign On)对于我们来说已经不陌生了.对于大型系统来说使用单点登录可以减少用户很多的麻烦.就拿百度来说吧,百度下面有很多的子 ...

  4. LSTM入门必读:从入门基础到工作方式详解 By 机器之心2017年7月24日 12:57 长短期记忆(LSTM)是一种非常重要的神经网络技术,其在语音识别和自然语言处理等许多领域都得到了广泛的应用

    LSTM入门必读:从入门基础到工作方式详解 By 机器之心2017年7月24日 12:57 长短期记忆(LSTM)是一种非常重要的神经网络技术,其在语音识别和自然语言处理等许多领域都得到了广泛的应用. ...

  5. 怎样进入android模式,安卓手机如何进入Recovery模式的通用方式详解

    2014-12-12 15:24:16 安卓手机如何进入Recovery模式的通用方式详解 标签:安卓 Recovery模式 教程 Recovery模式是什么?这里说的Recovery模式主要指的是安 ...

  6. @Resource,@Autowired,@Inject3种注入方式详解

    转载自 @Resource,@Autowired,@Inject3种注入方式详解 概况 @Resource,@Autowired,@Inject 这3种都是用来注入bean的,它们属于不同的程序中. ...

  7. python中with open写csv文件_Python中的CSV文件使用with语句的方式详解

    是否可以直接使用with语句与CSV文件?能够做这样的事情似乎很自然: import csv with csv.reader(open("myfile.csv")) as read ...

  8. mysql二进制方式_MySQL数据库之MySql二进制连接方式详解

    本文主要向大家介绍了MySQL数据库之MySql二进制连接方式详解 ,通过具体的内容向大家展现,希望对大家学习MySQL数据库有所帮助. 使用mysql二进制方式连接 您可以使用MySQL二进制方式进 ...

  9. 运用python的方式_对Python使用mfcc的两种方式详解

    1.Librosa import librosa filepath = "/Users/birenjianmo/Desktop/learn/librosa/mp3/in.wav" ...

最新文章

  1. POJ1042 Gone Fishing
  2. C#委托Action、ActionT、FuncT、PredicateT
  3. 调用Microsoft.Jet.OLEDB.4.0需要MDAC2.7支持
  4. 1-3 交换变量(算法竞赛入门经典)
  5. sqlite3使用简介
  6. LeetCode 164. 最大间距
  7. Openlayer 3 的画图测量面积
  8. js深拷贝和浅拷贝对数组的影响_javaScript中的深拷贝和浅拷贝
  9. 开课吧Java课堂:如何使用isAlive()和join()
  10. [Network Architecture]ResNext论文笔记(转)
  11. Linux看视频不卡的,Ubuntu 8.04下安装电视卡看电视
  12. ThinkPad键盘失灵解决办法
  13. 树莓派系统烧录 + 连接树莓派
  14. 《C++面向对象程序设计》✍千处细节、万字总结(建议收藏)
  15. Java基础 -> 为什么⽤线程池?线程池的创建?
  16. 测试网页版淘宝购物车
  17. ORA-12154 另一种解决方式,IIS发布后出现的---解决思路---终极方案
  18. 远程连接内网路由器下的电脑
  19. 毕业论文图片、公式自动编号和交叉索引教程——真的超好用
  20. python 实现轨迹数据可视化

热门文章

  1. 网络编程-之粘包现象
  2. 初识神经网络NeuralNetworks
  3. BZOJ 3544 treap (set)
  4. JDBC基础学习(三)—处理BLOB类型数据
  5. 第三章 可扩展标记语言XML
  6. java中log4j的详解(转)
  7. real210移植记录-u-boot2013.10引导linux3.10.30进入控制台
  8. gpio_direction_output 与 gpio_set_value
  9. 2.2 数个常用的特殊符号
  10. abb外部轴零位校准_RobotStudio软件:机器人自定义行走轴配置与仿真