转载请注明出处:jiq•钦'stechnical Blog

1、饿汉式

public class Singleton {
private final static Singleton INSTANCE = new Singleton();
private Singleton() { }
public static Singleton getInstance() {
return INSTANCE;
}
}

缺点:类载入时即分配空间。若不使用则较为占用内存空间。

2、懒汉式

2.1普通加锁模式

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

缺点:每一个线程调用getInstance都要加锁,效率低,我们想要仅仅在第一次调用getInstance时加锁。请看以下的双重检測方案

2.2占位符模式(推荐)

属于懒汉式单例,由于Java机制规定。内部类SingletonHolder仅仅有在getInstance()方法第一次调用的时候才会被载入(实现了lazy),并且其载入过程是线程安全的。内部类载入的时候实例化一次instance。

public class Singleton {
private Singleton() { }
privatestatic class SingletonHolder {
//内部类。第一次使用时才载入,且仅仅能SingletonHolder类能訪问
//特别注意:static域中改动共享变量是线程安全的,由JVM保障
static Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}

2.3双重检測

普通双重检測:

public class Singleton {
private static Singleton instance = null;
private Singleton() { }
public static Singleton getInstance() {
if(instance == null) {
synchronzied(Singleton.class) {
if(instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}

缺点:指令重排问题,參考我的这篇文章

解决方式:

针对instance实例变量用volatile修饰就能够了,volatile修饰的话就能够确保instance = new Singleton();相应的指令不会重排序:

public class Singleton {
private static volatile Singletoninstance = null; //以volatilekeyword修饰防止指令重排
private Singleton() { } //构造函数为私有,防止被实例化
public static Singleton getInstance() {
if(instance == null) { //双重检測
synchronzied(Singleton.class) {
if(instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}

Java并发:线程安全的单例模式的更多相关文章

  1. Java 并发 线程同步

    Java 并发 线程同步 @author ixenos 同步 1.异步线程本身包含了执行时需要的数据和方法,不需要外部提供的资源和方法,在执行时也不关心与其并发执行的其他线程的状态和行为 2.然而,大 ...

  2. Java 并发 线程的优先级

    Java 并发 线程的优先级 @author ixenos 低优先级线程的执行时刻 1.在任意时刻,当有多个线程处于可运行状态时,运行系统总是挑选一个优先级最高的线程执行,只有当线程停止.退出或者由于 ...

  3. Java 并发 线程属性

    Java 并发 线程属性 @author ixenos 线程优先级 1.每当线程调度器有机会选择新线程时,首先选择具有较高优先级的线程 2.默认情况下,一个线程继承它的父线程的优先级 当在一个运行的线 ...

  4. Java 并发 线程的生命周期

    Java 并发 线程的生命周期 @author ixenos 线程的生命周期 线程状态: a)     New 新建 b)     Runnable 可运行 c)     Running 运行 (调用 ...

  5. java的线程安全、单例模式、JVM内存结构等知识学习和整理

    知其然,不知其所以然 !在技术的海洋里,前路漫漫,我一直在迷失着自我. 欢迎访问我的csdn博客,我们一同成长! "不管做什么,只要坚持下去就会看到不一样!在路上,不卑不亢!" 博 ...

  6. Java并发——线程安全、线程同步、线程通信

    线程安全 进程间"共享"对象 多个“写”线程同时访问对象. 例:Timer实例的num成员,即add()方法是用的次数.即Timer实例是资源对象. class TestSync ...

  7. 从JDK源码角度看java并发线程的中断

    线程的定义给我们提供了并发执行多个任务的方式,大多数情况下我们会让每个任务都自行执行结束,这样能保证事务的一致性,但是有时我们希望在任务执行中取消任务,使线程停止.在java中要让线程安全.快速.可靠 ...

  8. Java并发——线程介绍

    前言: 互联网时代已经发展到了现在.从以前只考虑小流量到现在不得不去考虑高并发的问题.扯到了高并发的问题就要扯到线程的问题.你是否问过自己,你真正了解线程吗?还是你只知道一些其他博客里写的使用方法.下 ...

  9. java并发线程池---了解ThreadPoolExecutor就够了

    总结:线程池的特点是,在线程的数量=corePoolSize后,仅任务队列满了之后,才会从任务队列中取出一个任务,然后构造一个新的线程,循环往复直到线程数量达到maximumPoolSize执行拒绝策 ...

  10. java 并发——线程

    一.前言 前一篇文章总结了对 java 并发中的内置锁的理解,这篇文章来说说线程 ,并发与线程总有剪不断理还乱的关系.关于 java 线程的基本概念.线程与进程的关系以及如何创建线程,想必大家都很清楚 ...

随机推荐

  1. DataGridView 动态绑定 CheckBox

    下面演示如何在 DataGridView 中动态绑定 CheckBox: public class Test { /// <summary> /// 构造器 /// </summar ...

  2. python tkinter窗口置顶

    下面两句即可实现root窗口的置顶显示,可以用于某些程序的消息提示,能够弹出到桌面显示 root = Tk()root.wm_attributes('-topmost',1)

  3. Spring-security配置代码

    @Configuration public static class WebSecurityConfigurer extends WebSecurityConfigurerAdapter{ @Over ...

  4. js解析地址栏参数

    /** * 获取地址栏中url后面拼接的参数 * eg: * 浏览器地址栏中的地址:http://1.1.1.1/test.html?owner=2db08226-e2fa-426c-91a1-66e ...

  5. VC++常见错误原因解析--error LNK2019: 无法解析的外部符号 "public: void __thiscall

    根据个人遇到这个错误时的记录,原因可以分为一下几种: 原因一: 只是在.h里面声明了某个方法, 没有在cpp里面实现 . 具体讲,有时候在头文件中声明了需要的方法,确实忘记了在源文件中实现: 有时候在 ...

  6. 使用Micrisoft.net设计方案 第三章Web表示模式 Web模式集群详细介绍 Observer(观察器)

    在面向对象的编程中,对象同时包含数据和行为,这两者一起表示业务域的特定方面.使用对象生成应用程序的优点之一是可以将所有数据操作封装在对象内.这样, 就使对象成为独立的单位,并增加了在其他应用程序中重用 ...

  7. Android Error:Failed to resolve: com.afollestad:material-dialogs:

    背景: 同事把Android项目直接考给了我...我在Android Studio上运行,然后提示: Error:Failed to resolve: com.afollestad:material- ...

  8. 继续C#开发or转做产品

    本人今年大四,C#开发,在一家公司实习了一年后,面临一个选择,是继续C#开发还是转做产品?我C#开发能力目前还一般,但很有兴趣.也喜欢设计与创意,做过产品专员.求大婶们指导!

  9. python学习笔记(7)——集合(set)

    关键词#1.定义:无序不重复元素集, 基本功能包括关系测试和消除重复元素. 2.关键词:类似dict.只有key无value.常用于集合类数学运算. 3.创建 s=set() #入参可以是list.t ...

  10. 328.io流(字符串-练习-复制文本文件一)

    public static void main(String[] args) { // TODO Auto-generated method stub FileReader fr = null; Fi ...