从简单示例看对象的创建过程, 为什么双重检查的单例模式,分析Volatile关键字不能少
编译指令 :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 和 astore_1 这二条指令会发生指令重排,
比如一个 双重检查的单例模式:
class Singleton {
private Singleton() {
}
private volatile static Singleton INSTANCE;//这里没有使用 volatile 关键字
public static Singleton getInstance() {
if (INSTANCE == null) { //第1行
synchronized (Singleton.class) { //第2行
if (INSTANCE == null) { //第三行
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
INSTANCE = new Singleton(); //第四行
}
}
}
return INSTANCE;
}
public static void main(String[] args) {
for (int i = 0; i < 1000; i++) {
new Thread(()->{System.out.println(Singleton.getInstance().hashCode());}).start();
}
}
}
如果 没有volatile关键字,那么在 INSTANCE = new Singleton();这一行代码,new对象的时候,对应的clazz文件的 invokespecial 和 astore_1 这二条指令就有可能会发生指令重排,
先new了对象,此时对象创建处于半初始状态, 先执行了astore_1 建立了关联,后执行了 invokespecial, 就会导致, 第一行判断INSTANCE == null, 此时加锁,接下来判断 INSTANCE 为半初始化状态,并不为null, 那么这个单例模式就会失败
所以 这种双重检查的单例模式, volatile关键字不能少
从简单示例看对象的创建过程, 为什么双重检查的单例模式,分析Volatile关键字不能少的更多相关文章
- 图解JAVA对象的创建过程
前面几篇博文分别介绍了JAVA的Class文件格式.JVM的类加载机制和JVM的内存模型,这里就索性把java对象的创建过程一并说完,这样java对象的整个创建过程就基本上说明白了(当然你要有基础才能 ...
- Emit学习(2) - IL - 对象的创建过程
上一篇的介绍中, 并没有介绍到对象的创建过程, 这一篇主要就介绍一下, 对象的创建过程. 其实熟悉了IL语法之后, 完全可以用Reflector反编译代码去查看. 而且正因为有这个工具, 可以对照着R ...
- 深入理解Java对象的创建过程:类的初始化与实例化
摘要: 在Java中,一个对象在可以被使用之前必须要被正确地初始化,这一点是Java规范规定的.在实例化一个对象时,JVM首先会检查相关类型是否已经加载并初始化,如果没有,则JVM立即进行加载并调用类 ...
- (转)深入理解Java对象的创建过程
参考来源:http://blog.csdn.net/justloveyou_/article/details/72466416 摘要: 在Java中,一个对象在可以被使用之前必须要被正确地初始化,这一 ...
- Java对象的创建过程:类的初始化与实例化
一.Java对象创建时机 我们知道,一个对象在可以被使用之前必须要被正确地实例化.在Java代码中,有很多行为可以引起对象的创建,最为直观的一种就是使用new关键字来调用一个类的构造函数显式地创建对象 ...
- JAVA虚拟机:对象的创建过程
简要说明的话,Java对象的创建过程分为下面几步: 1.执行相关检查: 2.为对象分配内存,将分配到的内存空间都初始化为零值: 3.进行构造代码块和构造函数的初始化 下面详细介绍这几个步骤: 1.执行 ...
- 深入理解java虚拟机---对象的创建过程(八)
1.对象的创建过程 由于类的加载是一个很复杂的过程,所以这里暂时略过,后面会详细讲解,默认为是已加载过的类.着重强调对象的创建过程. 注意: 最后一步的init方法是代码块和构造方法. 以上是总图,下 ...
- HttpApplication 对象的创建过程及HttpModule过滤器的内部实现过程
最近通过Reflector学习了一下asp.net内部的原理,做做笔记,方便以后查阅. 先看下HttpApplication 对象的创建过程 从IHttpHandler applicationInst ...
- JVM中对象的创建过程
JVM中对象的创建过程如以下流程图中所示: 对其主要步骤进行详细阐述: 为新生对象分配内存: 内存的分配方式: 指针碰撞:假设Java堆中内存是绝对规整的,所有用过的内存放在一边,空闲的内存在另一边, ...
随机推荐
- UVA11078开放式学分制(前面-后面的最大值)
题意: 给你一个长度为n的整数序列a0 a1 a2..找出两个整数ai,aj(i<j),使得ai-aj最大. 思路: 简单题目,想象一下,对于每一个数我们只要用他前面的最 ...
- 神经网络与机器学习 笔记—多层感知器(MLP)
多层感知器(MLP) Rosenblatt感知器和LMS算法,都是单层的并且是单个神经元构造的神经网络,他们的局限性是只能解决线性可分问题,例如Rosenblatt感知器一直没办法处理简单异或问题.然 ...
- Redis中几种数据类型的基本操作指令
Redis基本指令 单线程+多路IO复用技术 1. Key 指令 作用 keys * 查看当前库所有键 exists <key> 判断此键是否存在 type <key> 查看键 ...
- spring和mybatis整合时Access denied for user '***'@'localhost' (using password: YES)错误的解决方案
参考文章:博客园文章 参考解决办法: 将数据库配置文件格式 key=value 改为 jdbc.key=value 以下为问题分析 使用Spring + Mybatis + Mysql整合时,测试报错 ...
- Codeforces Beta Round #73(Div2)
A - Chord 题意:就是环中有12个字符,给你三个字符,判断他们之间的间隔,如果第一个和第二个间隔是3并且第二个和第三个间隔是4,那么就输出minor,如果第一个和第二个间隔是4并且第二个和第三 ...
- Dart 2.13 版现已发布
作者 / Kevin Moore & Michael Thomsen Dart 2.13 版现已发布,其中新增了类型别名功能,这是目前用户呼声第二高的语言功能.Dart 2.13 还改进了 D ...
- mybaties longtext 类型不能映射到自动生成的文件
假设数据库里有 fun_detail 这样一个字段. 使用 MyBatis Generator 生成的 XXExample 文件,发现没有 fun_detail 这个字段. 需要加一行: <co ...
- jmeter自动停止监听--AutoStop Listener
如下图:
- 【转载】linux 安装 中文输入法 Fcitx 手动
在 Linux(测试版)中安装中文输入法 由于一些原因,目前在 Linux(测试版)中无法调用系统的输入法,故需要安装第三方输入法为 Linux(测试版)中的应用提供中文输入支持.本文档旨在介绍第三方 ...
- 电脑无法开机,用一个U盘先备份C盘部分重要文件并重装Win10系统的教程?
电脑无法开机,用一个U盘先备份C盘部分重要文件并重装Win10系统的教程.? 这应该是修电脑的万能方法,重装系统能解决绝大多数非硬件导致的电脑故障,但之前要备份一下桌面的一些个人文件.所以想学一下,以 ...