快速理解Java中的七种单例模式
饿汉式(推荐)
package concurencyv2.chapter1;
public class SingletonV2 {
private static final SingletonV2 instance = new SingletonV2();
private SingletonV2() {}
public static SingletonV2 getInstance() {
return instance;
}
}
优点:初试化静态的instance创建一次。如果我们在Singleton类里面写一个静态的方法不需要创建实例,它仍然会早早的创建一次实例。而降低内存的使用率。
缺点:没有lazy loading的效果,从而降低内存的使用率。
单线程下
package concurencyv2.chapter1;
public class SingletonV1 {
private static SingletonV1 instance = null;
private SingletonV1() {}
public SingletonV1 getInstance() {
if(null == instance)
instance = new SingletonV1();
return SingletonV1.instance;
}
}
注解: Singleton的静态属性instance中,只有instance为null的时候才创建一个实例,构造函数私有,确保每次都只创建一个,避免重复创建。
缺点:4只在单线程的情况下正常运行,在多线程的情况下,就会出问题。例如:当两个线程同时运行到判断instance是否为空的if语句,并且instance确实没有创建好时,那么两个线程都会创建一个实例。
懒汉式
package concurencyv2.chapter1;
public class SingletonV3 {
private SingletonV3() {
}
private static SingletonV3 instance;
public synchronized static SingletonV3 getInstance() {
if(null == instance)
instance = new SingletonV3();
return SingletonV3.instance;
}
}
注解:在单线程的基础上加上了同步锁,使得在多线程的情况下可以用。例如:当两个线程同时想创建实例,由于在一个时刻只有一个线程能得到同步锁,当第一个线程加上锁以后,第二个线程只能等待。第一个线程发现实例没有创建,创建之。第一个线程释放同步锁,第二个线程才可以加上同步锁,执行下面的代码。由于第一个线程已经创建了实例,所以第二个线程不需要创建实例。保证在多线程的环境下也只有一个实例。
缺点:每次通过getInstance方法得到singleton实例的时候都有一个试图去获取同步锁的过程。而众所周知,加锁是很耗时的。能避免则避免。
double check
package concurencyv2.chapter1;
public class SingletonV4 {
private SingletonV4() {
}
private static SingletonV4 instance;
public static SingletonV4 getInstance() {
if(null == instance) {
synchronized (SingletonV4.class) {
if(null == instance)
instance = new SingletonV4();
}
}
return SingletonV4.instance;
}
}
注解:只有当instance为null时,需要获取同步锁,创建一次实例。当实例被创建,则无需试图加锁。
缺点: 可能会出现空指针异常,一个线程获取了同步锁,并且创建了,但是还没有完成初始化。 另外一个线程直接getInstace,因此这个线程可能获取到的对象,有些地方没有初始化完成,造成引用的空指针现象。
double check and add volatile (推荐)
package concurencyv2.chapter1;
public class SingletonV5 {
private SingletonV5() {
}
private static volatile SingletonV5 instance;
public static SingletonV5 getInstance() {
if(null == instance) {
synchronized (SingletonV5.class) {
if(null == instance)
instance = new SingletonV5();
}
}
return SingletonV5.instance;
}
}
优点:在instance上添加了volatile,使得每次执行读操作的时候保证写操作已经完成.
静态内部类 (推荐)
package concurencyv2.chapter1;
public class SingletonV6 {
private SingletonV6() {}
private static class SingletonHolder {
public static final SingletonV6 instance = new SingletonV6();
}
public SingletonV6 getInstance() {
return SingletonHolder.instance;
}
}
枚举enum
package concurencyv2.chapter1;
public class SingletonV7 {
private SingletonV7() {
}
private enum Singleton {
SINGLETON;
private SingletonV7 instance;
Singleton() {
instance = new SingletonV7();
}
}
public static SingletonV7 getInstance() {
return Singleton.SINGLETON.instance;
}
}
利用enum只初始化一次的特性,保证了线程安全性.
快速理解Java中的七种单例模式的更多相关文章
- 快速理解Java中的五种单例模式
解法一:只适合单线程环境(不好) package test; /** * @author xiaoping * */ public class Singleton { private static S ...
- 快速理解Java中的五种单例模式(转)
解法一:只适合单线程环境(不好) package test; /** * @author xiaoping * */ public class Singleton { private static S ...
- Java中的五种单例模式实现方法
[代码] Java中的五种单例模式实现方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 2 ...
- java中的几种单例模式
目前比较常见的有4种(DCL为懒汉模式的线程安全版本). 单例模式的实现一般需要满足以下条件: 1.构造方法私有化,实例属性私有化. 2.必须仅在类的内部完成实例的初始化过程. 3.提供公共静态方法, ...
- 5000字 | 24张图带你彻底理解Java中的21种锁
本篇主要内容如下: 本篇文章已收纳到我的Java在线文档. Github 我的SpringCloud实战项目持续更新中 帮你总结好的锁: 序号 锁名称 应用 1 乐观锁 CAS 2 悲观锁 synch ...
- Java中的五种单例模式
Java模式之单例模式: 单例模式确保一个类只有一个实例,自行提供这个实例并向整个系统提供这个实例. 特点: 1,一个类只能有一个实例 2 自己创建这个实例 3 整个系统都要使用这个实例 例: 在下面 ...
- JDK学习---深入理解java中的HashMap、HashSet底层实现
本文参考资料: 1.<大话数据结构> 2.http://www.cnblogs.com/dassmeta/p/5338955.html 3.http://www.cnblogs.com/d ...
- 理解Java中的弱引用(Weak Reference)
本篇文章尝试从What.Why.How这三个角度来探索Java中的弱引用,理解Java中弱引用的定义.基本使用场景和使用方法.由于个人水平有限,叙述中难免存在不准确或是不清晰的地方,希望大家可以指出, ...
- JAVA基础学习之throws和throw的区别、Java中的四种权限、多线程的使用等(2)
1.throws和throw的区别 throws使用在函数外,是编译时的异常,throw使用在函数内,是运行时的异常 使用方法 public int method(int[] arr) throws ...
随机推荐
- Rpgmakermv(18)GALV RollCredits
原文: Galv's Roll Credits ---------------------------------------------------------------------------- ...
- poj2417 Baby-StepGiant-StepAlgorithm a^x=b%P
#include <iostream> #include <algorithm> #include <string.h> #include <cstdio&g ...
- hdu5371 manacher + 线段树
这题说的找出一个数组串 3等分 第一个部分和第3个部分一样,第二个部分和第一个部分回文,那么计算出这些字符串问这样的字符串最长为多少,我们先使用manacher 计算出每个位置以他为对称轴左边端点的最 ...
- QWidget 的 close 与 Qt::WA_DeleteOnClose
[1]close 与 Qt::WA_DeleteOnClose简介 1.1 Qt源码 /*! Closes this widget. Returns \c true if the widget was ...
- 关于Weex你需要知道的一切
QCon第一天,GMTC全球移动技术大会联席主席.手淘技术老大庄卓然(花名南天)在Keynote上宣布跨平台开发框架Weex开始内测,并将于6月份开源,同时他们也放出官网:http://alibaba ...
- web前端利用leaflet生成粒子风场,类似windy
wind.js如下: $(function() { var dixing = L.tileLayer.chinaProvider('Google.Satellite.Map', { maxZoom: ...
- bc 命令
bc命令是一种支持任意精度的交互执行的计算器语言.是Linux简单的计算器,能进行进制转换与计算.能转换的进制包括十六进制.十进制.八进制.二进制等.可以使用的运算符号包括(+)加法.(-)减法.(* ...
- .NET创建一个即是可执行程序又是Windows服务的程序
不得不说,.NET中安装服务很麻烦,即要创建Service,又要创建ServiceInstall,最后还要弄一堆命令来安装和卸载. 今天给大家提供一种方式,直接使用我们的程序来安装/卸载服务,并且可以 ...
- Django框架----权限组件(具体代码实现)
1.settings """ Django settings for day80 project. Generated by 'django-admin startpro ...
- 基于spring框架的jt项目分页查询知识点(二)
知识点汇总 1. 日志记录方法 private Logger log= Logger.getLogger(SysLogServiceImpl.class.getName()); 记录SysLogSer ...