单例模式实现方式详解
概念:
单例模式(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
单例模式实现方式详解相关推荐
- 【python教程入门学习】Python函数定义及传参方式详解(4种)
这篇文章主要介绍了Python函数定义及传参方式详解(4种),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 一.函数初识 1.定 ...
- php中 继承中的概念,JavaScript_JavaScript中的继承方式详解,js继承的概念
js里常用的如下 - phpStudy...
JavaScript中的继承方式详解 js继承的概念 js里常用的如下两种继承方式: 原型链继承(对象间的继承) 类式继承(构造函数间的继承) 由于js不像java那样是真正面向对象的语言,js是基于 ...
- SSO单点登录三种情况的实现方式详解
SSO单点登录三种情况的实现方式详解 单点登录(SSO--Single Sign On)对于我们来说已经不陌生了.对于大型系统来说使用单点登录可以减少用户很多的麻烦.就拿百度来说吧,百度下面有很多的子 ...
- LSTM入门必读:从入门基础到工作方式详解 By 机器之心2017年7月24日 12:57 长短期记忆(LSTM)是一种非常重要的神经网络技术,其在语音识别和自然语言处理等许多领域都得到了广泛的应用
LSTM入门必读:从入门基础到工作方式详解 By 机器之心2017年7月24日 12:57 长短期记忆(LSTM)是一种非常重要的神经网络技术,其在语音识别和自然语言处理等许多领域都得到了广泛的应用. ...
- 怎样进入android模式,安卓手机如何进入Recovery模式的通用方式详解
2014-12-12 15:24:16 安卓手机如何进入Recovery模式的通用方式详解 标签:安卓 Recovery模式 教程 Recovery模式是什么?这里说的Recovery模式主要指的是安 ...
- @Resource,@Autowired,@Inject3种注入方式详解
转载自 @Resource,@Autowired,@Inject3种注入方式详解 概况 @Resource,@Autowired,@Inject 这3种都是用来注入bean的,它们属于不同的程序中. ...
- python中with open写csv文件_Python中的CSV文件使用with语句的方式详解
是否可以直接使用with语句与CSV文件?能够做这样的事情似乎很自然: import csv with csv.reader(open("myfile.csv")) as read ...
- mysql二进制方式_MySQL数据库之MySql二进制连接方式详解
本文主要向大家介绍了MySQL数据库之MySql二进制连接方式详解 ,通过具体的内容向大家展现,希望对大家学习MySQL数据库有所帮助. 使用mysql二进制方式连接 您可以使用MySQL二进制方式进 ...
- 运用python的方式_对Python使用mfcc的两种方式详解
1.Librosa import librosa filepath = "/Users/birenjianmo/Desktop/learn/librosa/mp3/in.wav" ...
最新文章
- POJ1042 Gone Fishing
- C#委托Action、ActionT、FuncT、PredicateT
- 调用Microsoft.Jet.OLEDB.4.0需要MDAC2.7支持
- 1-3 交换变量(算法竞赛入门经典)
- sqlite3使用简介
- LeetCode 164. 最大间距
- Openlayer 3 的画图测量面积
- js深拷贝和浅拷贝对数组的影响_javaScript中的深拷贝和浅拷贝
- 开课吧Java课堂:如何使用isAlive()和join()
- [Network Architecture]ResNext论文笔记(转)
- Linux看视频不卡的,Ubuntu 8.04下安装电视卡看电视
- ThinkPad键盘失灵解决办法
- 树莓派系统烧录 + 连接树莓派
- 《C++面向对象程序设计》✍千处细节、万字总结(建议收藏)
- Java基础 -> 为什么⽤线程池?线程池的创建?
- 测试网页版淘宝购物车
- ORA-12154 另一种解决方式,IIS发布后出现的---解决思路---终极方案
- 远程连接内网路由器下的电脑
- 毕业论文图片、公式自动编号和交叉索引教程——真的超好用
- python 实现轨迹数据可视化
热门文章
- 网络编程-之粘包现象
- 初识神经网络NeuralNetworks
- BZOJ 3544 treap (set)
- JDBC基础学习(三)—处理BLOB类型数据
- 第三章 可扩展标记语言XML
- java中log4j的详解(转)
- real210移植记录-u-boot2013.10引导linux3.10.30进入控制台
- gpio_direction_output 与 gpio_set_value
- 2.2 数个常用的特殊符号
- abb外部轴零位校准_RobotStudio软件:机器人自定义行走轴配置与仿真