java 双重检查模式】的更多相关文章

java 双重检查模式 在并发环境下 兼顾安全和效率 成例(Idiom)是一种代码层次上的模式,是在比设计模式的层次更具体的层次上的代码技巧.成例往往与编程语言密切相关.双重检查成例(Double Check Idiom)是从C语言移植过来 的一种代码模式.   先看一个例子:   class Foo {     private Helper helper = null;     public Helper getHelper() {         if (helper == null) {…
双重检查锁定的由来在Java程序中,有时需要推迟一些高开销的对象的初始化操作,并且只有在真正使用到这个对象的时候,才进行初始化,此时,就需要延迟初始化技术.延迟初始化的正确实现是需要一些技巧的,否则容易出现问题,下面一一介绍. 方案1 public class UnsafeLazyInit{ private static Instance instance; public static Instance getInstance(){ if (instance == null){ instance…
单例类在Java开发者中非常常用,但是它给初级开发者们造成了很多挑战.他们所面对的其中一个关键挑战是,怎样确保单例类的行为是单例?也就是说,无论任何原因,如何防止单例类有多个实例.在整个应用生命周期中,要保证只有一个单例类的实例被创建,双重检查锁(Double checked locking of Singleton)是一种实现方法.顾名思义,在双重检查锁中,代码会检查两次单例类是否有已存在的实例,一次加锁一次不加锁,一次确保不会有多个实例被创建.顺便提一下,在JDK1.5中,Java修复了其内…
在 Effecitve Java 一书的第 48 条中提到了双重检查模式,并指出这种模式在 Java 中通常并不适用.该模式的结构如下所示: ? 1 2 3 4 5 6 7 8 9 10 public Resource getResource() {  if (resource == null) {    synchronized(this){     if (resource==null) {     resource = new Resource();     }     }   }  re…
首先这两种方式都是延迟初始化机制,就是当要用到的时候再去初始化. 但是Effective Java书中说过:除非绝对必要,否则就不要这么做. 1. DCL (double checked locking)双重检查: 如果出于性能的考虑而需要对实例域(注意这个属性并没有被static修饰)使用延迟初始化,就使用双重检查模式 public class Singleton { private volatile Singleton uniqueInstance; private Singleton(){…
尊重原创: http://gstarwd.iteye.com/blog/692937 2004 年 5 月 01 日 所有的编程语言都有一些共用的习语.了解和使用一些习语很有用,程序员们花费宝贵的时间来创建.学习和实现这些习语.问题是,稍后经过证明,一些习 语并不完全如其所声称的那样,或者仅仅是与描述的功能不符.在 Java 编程语言中,双重检查锁定就是这样的一个绝不应该使用的习语.在本文中,Peter Haggar 介绍了双重检查锁定习语的渊源,开发它的原因和它失效的原因.  编辑注 :本文在…
最初的代码 在最近的项目中,写出了这样的一段代码 private static SomeClass instance; public SomeClass getInstance() { if (null == instance) { instance = new SomeClass(); } return instance; } 然后在Code Review的时候被告知在多线程的情况下,这样写可能会导致instance有多个实例.比如下面这种情况: Time Thread A Thread B…
双重检查锁定(Double check locked)模式经常会出现在一些框架源码中,目的是为了延迟初始化变量.这个模式还可以用来创建单例.下面来看一个 Spring 中双重检查锁定的例子. 这个例子中需要将配置文件加载到 handlerMappings中,由于读取资源比较耗时,所以将动作放到真正需要 handlerMappings 的时候.我们可以看到 handlerMappings 前面使用了volatile .有没有想过为什么一定需要 volatile?虽然之前了解了双重检查锁定模式的原理…
Java基础教程:多线程杂谈——双重检查锁与Volatile 双重检查锁 有时候可能需要推迟一些高开销的对象初始化操作,并且只有在使用这些对象时才进行初始化.此时程序员可能会采用延迟初始化.但要正确实现线程安全的延迟初始化需要一些技巧,否则很容易出现问题.比如,下面是非线程安全的延迟初始化对象的示例代码: public class A{ private Instance instance; public Instance getInstance(){ if(instance==null){ in…
搬以前写的博客[2014-12-30 16:04] 在web应用中服务器面临的是大量的访问请求,免不了多线程程序,但是有时候,我们希望在多线程应用中的某一个类只能新建一个对象的时候,就会遇到问题. 首先考虑单线程,如果要求只能新建一个对象,那么构造函数我们要设为private.简单的想法: class singleton{ private singleton(){ //..... } private static singleton instance; public static singlet…
这个 Java 问题也常被问: 什么是线程安全的单例,你怎么创建它.好吧,在Java 5之前的版本, 使用双重检查锁定创建单例 Singleton 时,如果多个线程试图同时创建 Singleton 实例,则可能有多个 Singleton 实例被创建.从 Java 5 开始,使用 Enum 创建线程安全的Singleton很容易.但如果面试官坚持双重检查锁定,那么你必须为他们编写代码.记得使用volatile变量.…
一切真是有缘,上午刚刚看完单例模式,还在为其中的代码块同步而兴奋,下午就遇见这篇文章:双重检查锁定与延迟初始化.我一看,文章开头语出惊人,说这是一种错误的优化,我说,难道上午学的东西下午就过时了吗?仔细一看,发现了volatile的用处百度百科:violiate,而这正是上午我阅读时不得其解的地方,为什么要用这个呢,在<Head First设计模式>中只是简单说为了让多线程正确工作.而这篇文章,恰恰解决了我的这个疑惑,也就是uniqueInstance = new Instance()其实是分…
一.事先准备 首先准备一个运行用的代码: public class Singleton { public static void main(String[] args) { Thread[] threads = new Thread[10]; for (int i = 0; i < threads.length; i++) { threads[i] = new myThread(); } for (Thread thread : threads) { thread.start(); } } }…
java设计模式--单列模式 单列模式定义:确保一个类只有一个实例,并提供一个全局访问点. 下面是几种实现单列模式的Demo,每个Demo都有自己的优缺点: Demo1: /** * 单列模式需要满足下面三个条件: * 1.私有的构造函数 * 2.私有的引用变量 * 3.公开的静态方法(唯一获取该类单个实例的地方) * * @author Administrator */ public class AmericaPresident { private static AmericaPresiden…
被废弃的单例的DCL双重检查加锁/* *单例模式 *单例模式,保证一个类仅有一个实例,并提供一个访问它的全局访问点. *加同步锁的单例模式,适合在多线程中使用. */ class Singleton{ private static Singleton instance; private Singleton(){}//构造函数为private,外类不能使用new来创建立此类的实例 public static Singleton getInstance(){//获得实例的唯一全局访问点 System…
前言 从Java内存模型出发,结合并发编程中的原子性.可见性.有序性三个角度分析volatile所起的作用,并从汇编角度大致说了volatile的原理,说明了该关键字的应用场景:在这补充一点,分析下volatile是怎么在单例模式中避免双检锁出现的问题的.   并发编程的3个条件 1.原子性:要实现原子性方式较多,可用synchronized.lock加锁,AtomicInteger等,但volatile关键字是无法保证原子性的: 2.可见性:要实现可见性,也可用synchronized.loc…
背景:我们在实现单例模式的时候往往会忽略掉多线程的情况,就是写的代码在单线程的情况下是没问题的,但是一碰到多个线程的时候,由于代码没写好,就会引发很多问题,而且这些问题都是很隐蔽和很难排查的. 例子1:没有volatile修饰的uniqueInstance public class Singleton { private static Singleton uniqueInstance; private Singleton(){ } public static Singleton getInsta…
在Java并发编程时,同步都会存在着巨大的性能开销,因此,人们使用了很多的技巧来降低同步的影响,这其中有一些技巧很好,但是也有一些技巧存在一些缺陷,下面要结束的双重检查加锁(DCL)就是有缺陷的一类. 由于早期的JVM在性能上存在一些有待优化的地方,因此在并发编程中,延迟初始化经常被用来降低程序的开销.编写正确的延迟初始化需要使用同步,但是直接在初始化之前使用同步会对性能产生影响.所以一些人就提出了双重检查加锁,并声称能够解决这个矛盾.如图所示就是双重检查加锁的代码. 上图代码中,对Resour…
很好的文章,转自http://www.infoq.com/cn/articles/double-checked-locking-with-delay-initialization 在java程序中,有时候可能需要推迟一些高开销的对象初始化操作,并且只有在使用这些对象时才进行初始化.此时程序员可能会采用延迟初始化.但要正确实现线程安全的延迟初始化需要一些技巧,否则很容易出现问题.比如,下面是非线程安全的延迟初始化对象的示例代码: public class UnsafeLazyInitializat…
一.基本概念: 1.volatile是轻量级的synchronized,在多核处理器开发中保证了共享变量的“可见性”.可见性的意思是,当一个线程修改一个共享变量时,另一个线程能读到这个修改的值. 2.volatile在修饰共享变量进行写操作时,在多核处理器下会引发两件事情: 1)将当前处理器缓存行的数据写回到系统内存. 2)这个写回内存的操作会使在其他CPU里缓存了该内存地址的数据无效. 3.在多处理器下,为了保证各个处理器的缓存是一致的,就会实现缓存一致性协议.每个处理器通过嗅探在总线上传播的…
单利模式:确保一个类最多只有一个实例,并提供一个全局访问点. 经典单利模式创建对象代码 public class Singleton { private static Singleton uniqueInstance = null; private Singleton(){ } public static Singleton getInstance(){ if (uniqueInstance==null) { uniqueInstance=new Singleton(); } return un…
DCL,即Double Check Lock,中卫双重检查锁定. [Java并发编程]之十六:深入Java内存模型——happen-before规则及其对DCL的分析(含代码) 关于单例.关于DCL:Double Check Lock.关于volatile 单例模式.双检测锁定DCL.volatile Java内存模型之从JMM角度分析DCL 关于单例的DCL方式分析-…
Java设计模式-代理模式之动态代理(附源代码分析) 动态代理概念及类图 上一篇中介绍了静态代理,动态代理跟静态代理一个最大的差别就是:动态代理是在执行时刻动态的创建出代理类及其对象. 上篇中的静态代理是在编译的时候就确定了代理类详细类型.假设有多个类须要代理.那么就得创建多个. 另一点,假设Subject中新增了一个方法,那么相应的实现接口的类中也要相应的实现这些方法. 动态代理的做法:在执行时刻.能够动态创建出一个实现了多个接口的代理类.每一个代理类的对象都会关联一个表示内部处理逻辑的Inv…
背景 ​ 最近有一个场景遇到了数据库的并发问题.现在先由我来抽象一下,去掉不必要的繁杂业务. ​ 数据库表book存储着每本书的阅读量,一开始数据库是空的,不存在任何的数据.当用户访问接口的时候,判断表book是否存在此书的记录,如果不存在,即插入一条新记录,而且阅读量设置为1:当下个用户再阅读此书时,再调用接口就直接将此书的阅读量增加1,而不用再插入新记录. 并发下出现的问题 ​ 下面看一下伪代码: public void addOrUpdateBook{ Book oldBook = thi…
1 课程讲解 1.1 为何要使用双重检查 1.2 双重检查的缺点 1.3 指令重排序讲解 1.4 指令重排序比喻(自己理解) 1.5 如何解决指令重排序问题 2 代码演练 2.1 代码演练1(双重检查  解决对象锁和类锁的问题) 2.2 代码演练2(volatile 应用:解决重排序问题) 1 课程讲解 1.1 为何要使用双重检查 在上节课的时候,多线程的时候,由于一个线程被锁,其他的线程无法访问该类,被堵塞.性能大大降低,双重检查主要是应用解决此类问题. 双重检查可以使更多的线程堵塞在方法中,…
对象部分初始化:原理以及验证代码(双重检查锁与volatile相关) 对象部分初始化被称为 Partially initialized objects / Partially constructed objects / Incompletely initialized objects 这三种不同的说法描述的是同一种情况,即指令重排序(reorder)导致未完全初始化的对象被使用,这会导致某些错误的发生. 文章纯原创,转载请表明地址 目录 对象部分初始化:原理以及验证代码(双重检查锁与volati…
编译指令 :javac Test.java 反编译指令: javap -v Test 代码 public class ObjectTest { int m = 8; public static void main(String[] args) { ObjectTest o = new ObjectTest(); } } 安装jclasslib插件后,可以看到这个类的clazz文件: 如图所示: 这个是 对象的创建过程, 这个过程中有个半初始化状态, 这里的 invokespecial 和 ast…
JAVA 设计模式 组合模式 用途 组合模式 (Component) 将对象组合成树形结构以表示“部分-整体”的层次结构.组合模式使得用户对单个对象和组合对象的使用具有唯一性. 组合模式是一种结构型模式. 结构…
java 装饰者模式其实就是扩展子类的功能,和继承是一个性质. 但继承是在编译时就固定扩展了父类的一些功能,而装饰者模式是在运行过程中动态绑定对象,实现一个子类可以随时扩展功能. 将方法排列组合,也可以将其他子类的方法随时调用,但会new 出更多的对象. 个人感觉最核心的理解.自己做一下记录,代码晚上贴上.…
举两个例子以快速明白Java中的简单工厂模式: 女娲抟土造人话说:“天地开辟,未有人民,女娲抟土为人.”女娲需要用土造出一个个的人,但在女娲造出人之前,人的概念只存在于女娲的思想里面.女娲造人,这就是简单工厂模式的应用. 首先,在这个造人的思想里面,有几个重要的角色:女娲本身.抽象的人的概念和女娲所造出的一个个具体的人. 1.)女娲是一个工厂类,也就是简单工厂模式的核心角色. 2.)具休的一个个的人,包括张三,李四等.这些人便是简单工厂模式里面的具体产品角色 3.)抽象的人是最早只存在于女娲的头…