饿汉式(推荐)

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中的七种单例模式的更多相关文章

  1. 快速理解Java中的五种单例模式

    解法一:只适合单线程环境(不好) package test; /** * @author xiaoping * */ public class Singleton { private static S ...

  2. 快速理解Java中的五种单例模式(转)

    解法一:只适合单线程环境(不好) package test; /** * @author xiaoping * */ public class Singleton { private static S ...

  3. 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 ...

  4. java中的几种单例模式

    目前比较常见的有4种(DCL为懒汉模式的线程安全版本). 单例模式的实现一般需要满足以下条件: 1.构造方法私有化,实例属性私有化. 2.必须仅在类的内部完成实例的初始化过程. 3.提供公共静态方法, ...

  5. 5000字 | 24张图带你彻底理解Java中的21种锁

    本篇主要内容如下: 本篇文章已收纳到我的Java在线文档. Github 我的SpringCloud实战项目持续更新中 帮你总结好的锁: 序号 锁名称 应用 1 乐观锁 CAS 2 悲观锁 synch ...

  6. Java中的五种单例模式

    Java模式之单例模式: 单例模式确保一个类只有一个实例,自行提供这个实例并向整个系统提供这个实例. 特点: 1,一个类只能有一个实例 2 自己创建这个实例 3 整个系统都要使用这个实例 例: 在下面 ...

  7. JDK学习---深入理解java中的HashMap、HashSet底层实现

    本文参考资料: 1.<大话数据结构> 2.http://www.cnblogs.com/dassmeta/p/5338955.html 3.http://www.cnblogs.com/d ...

  8. 理解Java中的弱引用(Weak Reference)

    本篇文章尝试从What.Why.How这三个角度来探索Java中的弱引用,理解Java中弱引用的定义.基本使用场景和使用方法.由于个人水平有限,叙述中难免存在不准确或是不清晰的地方,希望大家可以指出, ...

  9. JAVA基础学习之throws和throw的区别、Java中的四种权限、多线程的使用等(2)

    1.throws和throw的区别 throws使用在函数外,是编译时的异常,throw使用在函数内,是运行时的异常 使用方法 public int method(int[] arr) throws ...

随机推荐

  1. python windows 下pip easy_install 使用错误的问题

    最近电脑重装了系统,又重新安装python .在官网下载了安装包后电脑成功安装了,但使用pip命令时出现以下错误 Fatal error in launcher: Unable to create p ...

  2. nw.js package一般设置

    { "name": "app name", "main": "mainpage",                    ...

  3. hdu 5126 cdq+Treap+BIT

    这题说的是给了三维空间然后操作 寻求在 x1,y1,z1    x2, y2, z2; (x1<x2, y1<y2,z1<z2) 计算出在 以这两个端点为右下和左上端点的方体内的点的 ...

  4. CSS背景与边框属性-----box-shadow

    box-shadow:none | <shadow> [ , <shadow> ]*   <shadow> = inset? && <leng ...

  5. DeepLearning资源汇总

    仍旧不完全统计,边学边加 Bagging与随机森林算法原理 分类数据集 MNIST Cifar10 ILSVRC排行榜 Cifar10 board train loss与test loss结果分析   ...

  6. 做一次面向对象的体操:将JSON字符串转换为嵌套对象的一种方法

    背景与问题 在 <一个略复杂的数据映射聚合例子及代码重构> 一文中,将一个JSON字符串转成了所需要的订单信息Map.尽管做了代码重构和配置化,过程式的代码仍然显得晦涩难懂,并且客户端使用 ...

  7. python pymssql 连接数据库

    1)写在前面 远程连接数据库的时候,端口前面都是用的逗号, 因为惯性思维, 就傻傻的把    ip+,+端口 赋值给server了,然后一直报错, pymssql.InterfaceError: Co ...

  8. PLSQL 问题小记

    问题1:在一个拼写长字符串的函数中,若出现ora-06502或者ora-06512的错误,则有可能是在拼串的过程中,数据类型的隐式转换出了问题,如:字符类型转为数字,此时会出现错误. 解决方案:在拼串 ...

  9. <转>jmeter(九)逻辑控制器

    本博客转载自:http://www.cnblogs.com/imyalost/category/846346.html 个人感觉不错,对jmeter讲解非常详细,担心以后找不到了,所以转发出来,留着慢 ...

  10. 服务器网络地址 "TCP://XXX:5022" 无法访问或不存在。请检查网络地址

    把主机上数据库,完整备份一份库文件和事务日志文件,“with non recover”方式还原过去,再重新执行SQL指令.当跨IP段的时候就需要在主备机的 C:\Windows\System32\dr ...