文档章节

Java的几种单例模式及特点

Mrling
 Mrling
发布于 2017/09/08 17:10
字数 1199
阅读 16
收藏 1
点赞 0
评论 0

1、Java常见的单例模式(懒汉、饿汉、双重锁模式)


       

    1.1饿汉模式   

public class Singleton_e {
	private static final Singleton_e instance = new Singleton_e();
	private Singleton_e() {
		System.out.println("这是单例模式之:饿汉模式");
	}
	public static Singleton_e getInstance() {
		return instance;
	}
}

    从时间和空间方面分析: 饿汉式是典型的空间换时间,当类装载的时候就会创建类实例,不管你用不用,先创建出来,然后每次调用的时候,就不需要再判断了,节省了运行时间。

    从线程安全方面分析:饿汉式是线程安全的,因为虚拟机保证只会装载一次,在装载类的时候是不会发生并发的。

    1.2懒汉模式

public class Singleton_lan {
	private static Singleton_lan instance = null;
	private Singleton_lan() {
		System.err.println("这是单例模式之:懒汉模式");
	}
	public static synchronized Singleton_lan getInstance() {
		if (instance == null) {
			instance = new Singleton_lan();
		}
		return instance;
	}
}

    从时间和空间方面分析: 懒汉式是典型的时间换空间,也就是每次获取实例都会进行判断,看是否需要创建实例,浪费判断的时间。当然,如果一直没有人使用的话,那就不会创建实例,则节约内存空间。
    从线程安全方面分析:懒汉式从线程安全性上讲,不加同步的懒汉式是线程不安全的,比如,有两个线程,一个是线程A,一个是线程B,它们同时调用getInstance方法,那就可能导致并发问题

    1.3双重检查锁模式(DCL)

public class Singleton_shuangchongsuo {
	private static Singleton_shuangchongsuo instance = null;
	private Singleton_shuangchongsuo() {
		System.out.println("这是单例模式之:双重锁模式");//(1)
	}

	public static Singleton_shuangchongsuo getInstance() {
		if (instance == null) {//(2)
			synchronized (instance) {//(3)
				if (instance == null) {//(4)
					instance = new Singleton_shuangchongsuo();//(5)
				}
			}
		}
		return instance;//(6)
	}
}

    双重锁模式简称DCL(double check lock)相当于对懒汉模式进行了增强,保证多线程访问时安全问题(但是不符合happens-before原则,后面会讨论)。

    当然如果直接在Singleton_shuangchongsuo()方法上加锁也可以达到目的,但是这样的话,每次获取实例都要去判断一下是否加锁,造成效率低下。而双重锁只会在特殊情况(第一次创建实例instance时,可能会产生多个实例同时访问的情况下)才会判断锁是哪个,相对效率高。

1.4、用happens-before规则重新审视双重检查锁模式(DCL)

我想简单的用对象创建期间的实际场景来分析一下:(以下是我的个人的理解,所看的资料也是非官方的,不完全保证正确。)

还是看上面1.3双重锁模式的代码,假设线程1执行完(5)时,线程2正好执行到了(2);
看看 new Singleton_shuangchongsuo(); 这个语句的执行过程: 它不是一个原子操作,实际是由多个步骤,我们从我们关注的角度简化一下,简单的认为它主要有2步操作好了:
a) 在内存中分配空间,并将引用指向该内存空间。
b) 执行对象的初始化的逻辑(和操作),完成对象的构建。

此时因为线程1和线程2没有用同步,他们之间不存在“Happens-Before”规则的约束,所以在线程1创建Singleton_shuangchongsuo对象的 a),b)这两个步骤对于线程2来说会有可能出现a)可见,b)不可见
造成了线程2获取到了一个未创建完整的Singleton_shuangchongsuo对象引用,为后边埋下隐患。

改进后的DCL代码:

public class Singleton_lan2 {
	private Singleton_lan2(){
		System.out.println("这是对饿懒模式的的增强,解决由双重锁模式代码未遵循happens-before原则带来的问题");
	}
	private static class InstanceHolder {//1 static 
		private static final  Singleton_lan2 instance = new Singleton_lan2();//2 static 
	}
	public static Singleton_lan2 getInstance(){//3 该static保证不需要实例化Singleton_lan2调用该静态方法
		return InstanceHolder.instance;//通过1、2的static关键字保证可以访问静态类中的静态变量
	}
}

    以上代码是通过静态内部类的方式实现。当getInstance方法第一次被调用的时候,它第一次读取InstanceHolder.instance,导致InstanceHolder类得到初始化;而这个类在装载并被初始化的时候,会初始化它的静态域,从而创建Singleton的实例,由于是静态的域,因此只会在虚拟机装载类的时候初始化一次,并由虚拟机来保证它的线程安全性。这个模式的优势在于,getInstance方法并没有被同步,并且只是执行一个域的访问,因此延迟初始化并没有增加任何访问成本。

 

 

 

更多相关DCL的修正请参考以下文章:

http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html

参考文章:http://ifeve.com/java-concurrent-hashmap-1/

更详细解释可以看这里:http://www.javaeye.com/topic/260515?page=1   

 

 

© 著作权归作者所有

共有 人打赏支持
Mrling
粉丝 2
博文 7
码字总数 7277
作品 0
丰台
程序员
20个设计模式和软件设计面试问题

不管是参加Java面试还是C#面试,设计模式和软件设计都是任何编程面试中的必问问题。实际上,编程能力和设计技巧是对彼此很好的补充。一个好的程序员通常都是一个好的软件设计人员。他们知道怎...

LCZ777
2014/08/13
0
0
设计模式3——Proxy设计模式

Proxy代理设计模式是一种控制对象访问的设计模式,类似于网络代理,网络代理机制如下图: Proxy代理设计模式机制如下: 代理模式UML图如下: 代理模式顺序图如下: 客户端程序通过代理程序来...

小米米儿小
2013/12/06
0
0
设计模式15——Template Method设计模式

Template Method模板方法设计模式定义一个操作中算法的骨架,将具体步骤的执行延迟到子类中实现。Java中的抽象类就是使用了模板方法设计模式。模板方法设计模式结构如下: 以文档处理为例,T...

小米米儿小
2014/01/24
0
0
设计模式 2014-12-19

book: 阎宏《JAVA与模式》 架构设计栏目 http://blog.csdn.net/enterprise/column.html 概要: http://bbs.csdn.net/forums/Embeddeddriver 23种设计模式分别是: 1.单例模式 2.工厂方法模式...

jayronwang
2014/12/19
0
0
简单工厂、工厂方法、抽象工厂、策略模式、策略与工厂的区别

转载:原地址http://www.cnblogs.com/zhangchenliang/p/3700820.html 简单工厂、工厂方法、抽象工厂、策略模式、策略与工厂的区别 结合简单示例和UML图,讲解工厂模式简单原理。 一、引子 话说...

法斗斗
05/08
0
0
java中23种设计模式(上)

参考网址:http://blog.csdn.net/zhangerqing 资源:http://download.csdn.net/detail/zhangerqing/4835830 设计模式(Design Patterns) 设计模式(Design pattern)是一套被反复使用、多数...

青涩的梦
06/26
0
0
Java语言中单例模式的四种写法

作为设计模式理论中的Helloworld,相信学习java语言的人,都应该听说过单例模式。单例模式作为对象的一种创建模式,它的作用是确保某一个类在整个系统中只有一个实例,而且自行实例化并向整个...

相见欢
2013/02/03
0
20
【23种设计模式之一】单例设计模式(翻译)

引言: 这一系列文章,翻译自网络上的文章,不过中间会夹杂着个人的理解,非原创,不过中文应该算是原创。 下面介绍,使用设计模式的一些好处: 1、设计模式是已经在工业生产中使用的,用于解...

敲代码猥琐男
2015/01/13
0
2
设计模式之「观察者模式」(Observer)

简单地说,观察者模式定义了一个一对多的依赖关系,让一个或多个观察者对象监察一个主题对象。这样一个主题对象在状态上的变化能够通知所有的依赖于此对象的那些观察者对象,使这些观察者对象...

柳哥
2014/12/16
0
0
Java之美[从菜鸟到高手演变]之设计模式二

我们接着讨论设计模式,上篇文章我讲完了5种创建型模式,这章开始,我将讲下7种结构型模式:适配器模式、装饰模式、代理模式、外观模式、桥接模式、组合模式、享元模式。其中对象的适配器模式...

只想一个人静一静
2014/02/25
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

OSChina 周三乱弹 —— 你被我从 osc 老婆们名单中踢出了

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @小鱼丁:分享五月天的单曲《后来的我们 (电影《后来的我们》片名曲)》: 《后来的我们 (电影《后来的我们》片名曲)》- 五月天 手机党少年们想...

小小编辑
8分钟前
3
1
Spring Boot Admin 2.0开箱体验

概述 在我之前的 《Spring Boot应用监控实战》 一文中,讲述了如何利用 Spring Boot Admin 1.5.X 版本来可视化地监控 Spring Boot 应用。说时迟,那时快,现在 Spring Boot Admin 都更新到 ...

CodeSheep
28分钟前
0
0
Python + Selenium + Chrome 使用代理 auth 的用户名密码授权

米扑代理,全球领导的代理品牌,专注代理行业近十年,提供开放、私密、独享代理,并可免费试用 米扑代理官网:https://proxy.mimvp.com 本文示例,是结合米扑代理的私密、独享、开放代理,专...

sunboy2050
今天
0
0
实现异步有哪些方法

有哪些方法可以实现异步呢? 方式一:java 线程池 示例: @Test public final void test_ThreadPool() throws InterruptedException { ScheduledThreadPoolExecutor scheduledThre......

黄威
今天
1
0
linux服务器修改mtu值优化cpu

一、jumbo frames 相关 1、什么是jumbo frames Jumbo frames 是指比标准Ethernet Frames长的frame,即比1518/1522 bit大的frames,Jumbo frame的大小是每个设备厂商规定的,不属于IEEE标准;...

六库科技
今天
0
0
牛客网刷题

1. 二维数组中的查找(难度:易) 题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入...

大不了敲一辈子代码
今天
0
0
linux系统的任务计划、服务管理

linux任务计划cron 在linux下,有时候要在我们不在的时候执行一项命令,或启动一个脚本,可以使用任务计划cron功能。 任务计划要用crontab命令完成 选项: -u 指定某个用户,不加-u表示当前用...

黄昏残影
昨天
0
0
设计模式:单例模式

单例模式的定义是确保某个类在任何情况下都只有一个实例,并且需要提供一个全局的访问点供调用者访问该实例的一种模式。 实现以上模式基于以下必须遵守的两点: 1.构造方法私有化 2.提供一个...

人觉非常君
昨天
0
0
《Linux Perf Master》Edition 0.4 发布

在线阅读:https://riboseyim.gitbook.io/perf 在线阅读:https://www.gitbook.com/book/riboseyim/linux-perf-master/details 百度网盘【pdf、mobi、ePub】:https://pan.baidu.com/s/1C20T......

RiboseYim
昨天
1
0
conda 换源

https://mirrors.tuna.tsinghua.edu.cn/help/anaconda/ conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/conda config --add channels https://mir......

阿豪boy
昨天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部