一.基本概念: 1.volatile是轻量级的synchronized,在多核处理器开发中保证了共享变量的“可见性”.可见性的意思是,当一个线程修改一个共享变量时,另一个线程能读到这个修改的值. 2.volatile在修饰共享变量进行写操作时,在多核处理器下会引发两件事情: 1)将当前处理器缓存行的数据写回到系统内存. 2)这个写回内存的操作会使在其他CPU里缓存了该内存地址的数据无效. 3.在多处理器下,为了保证各个处理器的缓存是一致的,就会实现缓存一致性协议.每个处理器通过嗅探在总线上传播的…
很好的文章,转自http://www.infoq.com/cn/articles/double-checked-locking-with-delay-initialization 在java程序中,有时候可能需要推迟一些高开销的对象初始化操作,并且只有在使用这些对象时才进行初始化.此时程序员可能会采用延迟初始化.但要正确实现线程安全的延迟初始化需要一些技巧,否则很容易出现问题.比如,下面是非线程安全的延迟初始化对象的示例代码: public class UnsafeLazyInitializat…
双重检查锁定的由来在Java程序中,有时需要推迟一些高开销的对象的初始化操作,并且只有在真正使用到这个对象的时候,才进行初始化,此时,就需要延迟初始化技术.延迟初始化的正确实现是需要一些技巧的,否则容易出现问题,下面一一介绍. 方案1 public class UnsafeLazyInit{ private static Instance instance; public static Instance getInstance(){ if (instance == null){ instance…
一切真是有缘,上午刚刚看完单例模式,还在为其中的代码块同步而兴奋,下午就遇见这篇文章:双重检查锁定与延迟初始化.我一看,文章开头语出惊人,说这是一种错误的优化,我说,难道上午学的东西下午就过时了吗?仔细一看,发现了volatile的用处百度百科:violiate,而这正是上午我阅读时不得其解的地方,为什么要用这个呢,在<Head First设计模式>中只是简单说为了让多线程正确工作.而这篇文章,恰恰解决了我的这个疑惑,也就是uniqueInstance = new Instance()其实是分…
尊重原创: http://gstarwd.iteye.com/blog/692937 2004 年 5 月 01 日 所有的编程语言都有一些共用的习语.了解和使用一些习语很有用,程序员们花费宝贵的时间来创建.学习和实现这些习语.问题是,稍后经过证明,一些习 语并不完全如其所声称的那样,或者仅仅是与描述的功能不符.在 Java 编程语言中,双重检查锁定就是这样的一个绝不应该使用的习语.在本文中,Peter Haggar 介绍了双重检查锁定习语的渊源,开发它的原因和它失效的原因.  编辑注 :本文在…
DCL,即Double Check Lock,中卫双重检查锁定. [Java并发编程]之十六:深入Java内存模型——happen-before规则及其对DCL的分析(含代码) 关于单例.关于DCL:Double Check Lock.关于volatile 单例模式.双检测锁定DCL.volatile Java内存模型之从JMM角度分析DCL 关于单例的DCL方式分析-…
背景 ​ 最近有一个场景遇到了数据库的并发问题.现在先由我来抽象一下,去掉不必要的繁杂业务. ​ 数据库表book存储着每本书的阅读量,一开始数据库是空的,不存在任何的数据.当用户访问接口的时候,判断表book是否存在此书的记录,如果不存在,即插入一条新记录,而且阅读量设置为1:当下个用户再阅读此书时,再调用接口就直接将此书的阅读量增加1,而不用再插入新记录. 并发下出现的问题 ​ 下面看一下伪代码: public void addOrUpdateBook{ Book oldBook = thi…
问题描述 现在,不管开发一个多大的系统(至少我现在的部门是这样的),都会带一个日志功能:在实际开发过程中,会专门有一个日志模块,负责写日志,由于在系统的任何地方,我们都有可能要调用日志模块中的函数,进行写日志.那么,如何构造一个日志模块的实例呢?难道,每次new一个日志模块实例,写完日志,再delete,不要告诉我你是这么干的.在C++中,可以构造一个日志模块的全局变量,那么在任何地方就都可以用了,是的,不错.但是,我所在的开发部门的C++编码规范是参照Google的编码规范的. 全局变量在项目…
问题描述 现在,不管开发一个多大的系统(至少我现在的部门是这样的),都会带一个日志功能:在实际开发过程中,会专门有一个日志模块,负责写日志,由于在系统的任何地方,我们都有可能要调用日志模块中的函数,进行写日志.那么,如何构造一个日志模块的实例呢?难道,每次new一个日志模块实例,写完日志,再delete,不要告诉我你是这么干的.在C++中,可以构造一个日志模块的全局变量,那么在任何地方就都可以用了,是的,不错.但是,我所在的开发部门的C++编码规范是参照Google的编码规范的. 全局变量在项目…
背景:我们在实现单例模式的时候往往会忽略掉多线程的情况,就是写的代码在单线程的情况下是没问题的,但是一碰到多个线程的时候,由于代码没写好,就会引发很多问题,而且这些问题都是很隐蔽和很难排查的. 例子1:没有volatile修饰的uniqueInstance public class Singleton { private static Singleton uniqueInstance; private Singleton(){ } public static Singleton getInsta…