双重锁实现单例时遭到质疑,既是:双重锁也无法保证单例模式!

原因是:指令会重排序,普通的变量仅仅会保证该方法在执行时,所有依赖的赋值结果是正确的,但不会保证执行顺序!

为什么会重排序:指令重排序是指cpu采用了允许将多条指令不按照程序的顺序分开发送各相应电路单元处理,cpu不会任意排序(深入java虚拟机第12章),但需要重排序提高性能。

怎么解决,标题也写明白了。

使用volatile关键字!

为什么使用volatile关键字可以实现:此关键字会禁止指令重排序,即:增加了内存屏障!

如果是一个cpu内存屏障是毫无意义的,如果是多cpu访问同一块内存,并且其中一个在观测另一个,就需要内存屏障来保证一执行了。

如果你打开编译后的代码清单,会看到加入volatile关键字的变量会多一条指令:lock addl $0x0 ,(%esp)

此指令很有意义:lock addl $0x0 指令的作用是使当前cpu的cache值写入内存,该写入操作也会引起其他cpu或者内核无效化其cache,既是是做了一个空操作(store、write),可以让volatile变量对其他cpu立即可见!

 public class Singleton {

     private volatile static Singleton singleton = null;

     public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}

另外:volatile屏蔽指令重排序的语义,在jdk1.5中才被完全修复!

volatile双重锁实现单例的更多相关文章

  1. 双重检查锁实现单例(java)

    单例类在Java开发者中非常常用,但是它给初级开发者们造成了很多挑战.他们所面对的其中一个关键挑战是,怎样确保单例类的行为是单例?也就是说,无论任何原因,如何防止单例类有多个实例.在整个应用生命周期中 ...

  2. effectivejava(破坏单例)

    以下代码是最普通的双重锁的单例实现形式 package com.edu.character02; import java.io.Serializable; /** * <p> * 双重锁 ...

  3. Effective Java - 构造器私有、枚举和单例

    目录 饿汉式单例 静态常量 静态代码块 懒汉式单例 尝试加锁 同步代码块 双重检查 静态内部类单例 枚举单例 Singleton 是指仅仅被实例化一次的类.Singleton代表了无状态的对象像是方法 ...

  4. Java设计模式:Singleton(单例)模式

    概念定义 Singleton(单例)模式是指在程序运行期间, 某些类只实例化一次,创建一个全局唯一对象.因此,单例类只能有一个实例,且必须自己创建自己的这个唯一实例,并对外提供访问该实例的方式. 单例 ...

  5. Java单例和多例

    背景:最近在学习韩老师的笔记时候发现不是很了解单例和多例,于是通过网上查找资料的方式去学习. 设计模式:最佳的实践,是软件开发人员在软件开发过程中面临一般解决方案,也就是开发的经验总结. 单例模式(S ...

  6. 【Java学习笔记之三十】详解Java单例(Singleton)模式

    概念: Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建 ...

  7. javaWeb项目中到底什么是单例,多例

    你用杯子喝可乐,喝完了不刷,继续去倒果汁喝,就是单例.你用杯子喝可乐,直接扔了杯子,换个杯子去倒果汁喝,就是多例. 数据库连接池就是单例模式,有且仅有一个连接池管理者,管理多个连接池对象. 1. 什么 ...

  8. java设计模式--解决单例设计模式中懒汉式线程安全问题

    首先写个单例,懒汉模式: public class SingleDemo { private static SingleDemo s = null; private SingleDemo(){} pu ...

  9. 转载 单例(Singleton)模式)的误区

    在创建型模式中,单例(Singleton)模式和原型(Prototype)模式相对来说其用意更为简单明了.单例(Singleton)模式确保某类只有一个实例,且自行实例化并向整个系统提供这个实例:原型 ...

随机推荐

  1. shell---rpm

    [root@master src]# rpm -qpl epel-release-latest-6.noarch.rpm         ##查询该rpm包安装了什么warning: epel-rel ...

  2. BZOJ_2716_[Violet 3]天使玩偶&&BZOJ_2648_SJY摆棋子_KDTree

    BZOJ_2716_[Violet 3]天使玩偶&&BZOJ_2648_SJY摆棋子_KDTree Description 这天,SJY显得无聊.在家自己玩.在一个棋盘上,有N个黑色棋 ...

  3. js 父组件向子组件传参

    有一个父组件页面如上,点击新增或者修改都会弹出同一个子组件如下: 父组件传参到子组件有两种方式: 一.直接把对象当成参数传给子组件,(看上去更简单,经测试发现一个问题,因为新增时要置空对象的所有信息, ...

  4. C++类对象之间的类型转换和重载

    类对象和其他类型对象的转换 转换场合有: 赋值转换 表达式中的转换 显式转换 函数调用, 传递参数时的转换 转换方向有: 由定义类向其他类型的转换 由其他类型向定义类的转换 #include < ...

  5. epoll的一个使用例子

    使用到主要函数有: #include <sys/epoll.h> int epoll_create(int size); int epoll_create1(int flags); int ...

  6. 转 vs2008使用技巧推荐

    Visual Studio 2008自带的1000多个 Windows 系统使用的各种图标.光标和动画文件在Visual Studio 2008的安装目录下,\Microsoft Visual Stu ...

  7. 抓屏工具 faststone capture

    百度百科 http://baike.baidu.com/link?url=te51CfOKYIEmqT1jsyRwcB8Pnals5xQ8nUXk6trvBPGSJRBO5G7BEZL7cYQxmx8 ...

  8. 高级java工程师面试题-随笔

    最近打算要换工作,也面试了几家,因为不是自己喜欢的所以拒了一些(当然也有人家不要我的.....).在面试的过程中发现对java高级程序员的考察基本上围绕知识面,知识深度两个方面来考察.下面是在面试过程 ...

  9. Flutter实战视频-移动电商-37.路由_Fluro引入和商品详细页建立

    37.路由_Fluro引入和商品详细页建立 https://github.com/theyakka/fluro pages/details_page.dart新建页面 使用路由 先添加路由插件的引用 ...

  10. Laravel中的模板引擎Blade

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...