编译指令 :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关键字不能少的更多相关文章

  1. 图解JAVA对象的创建过程

    前面几篇博文分别介绍了JAVA的Class文件格式.JVM的类加载机制和JVM的内存模型,这里就索性把java对象的创建过程一并说完,这样java对象的整个创建过程就基本上说明白了(当然你要有基础才能 ...

  2. Emit学习(2) - IL - 对象的创建过程

    上一篇的介绍中, 并没有介绍到对象的创建过程, 这一篇主要就介绍一下, 对象的创建过程. 其实熟悉了IL语法之后, 完全可以用Reflector反编译代码去查看. 而且正因为有这个工具, 可以对照着R ...

  3. 深入理解Java对象的创建过程:类的初始化与实例化

    摘要: 在Java中,一个对象在可以被使用之前必须要被正确地初始化,这一点是Java规范规定的.在实例化一个对象时,JVM首先会检查相关类型是否已经加载并初始化,如果没有,则JVM立即进行加载并调用类 ...

  4. (转)深入理解Java对象的创建过程

    参考来源:http://blog.csdn.net/justloveyou_/article/details/72466416 摘要: 在Java中,一个对象在可以被使用之前必须要被正确地初始化,这一 ...

  5. Java对象的创建过程:类的初始化与实例化

    一.Java对象创建时机 我们知道,一个对象在可以被使用之前必须要被正确地实例化.在Java代码中,有很多行为可以引起对象的创建,最为直观的一种就是使用new关键字来调用一个类的构造函数显式地创建对象 ...

  6. JAVA虚拟机:对象的创建过程

    简要说明的话,Java对象的创建过程分为下面几步: 1.执行相关检查: 2.为对象分配内存,将分配到的内存空间都初始化为零值: 3.进行构造代码块和构造函数的初始化 下面详细介绍这几个步骤: 1.执行 ...

  7. 深入理解java虚拟机---对象的创建过程(八)

    1.对象的创建过程 由于类的加载是一个很复杂的过程,所以这里暂时略过,后面会详细讲解,默认为是已加载过的类.着重强调对象的创建过程. 注意: 最后一步的init方法是代码块和构造方法. 以上是总图,下 ...

  8. HttpApplication 对象的创建过程及HttpModule过滤器的内部实现过程

    最近通过Reflector学习了一下asp.net内部的原理,做做笔记,方便以后查阅. 先看下HttpApplication 对象的创建过程 从IHttpHandler applicationInst ...

  9. JVM中对象的创建过程

    JVM中对象的创建过程如以下流程图中所示: 对其主要步骤进行详细阐述: 为新生对象分配内存: 内存的分配方式: 指针碰撞:假设Java堆中内存是绝对规整的,所有用过的内存放在一边,空闲的内存在另一边, ...

随机推荐

  1. XCTF-unfinish

    unfinish 之前做过这个题,这是之前写的WP:链接

  2. springmvcdemo

      项目点击属性  2.3  转换成2.5    已经变成一个网站项目了     报错消失 pom.xml <project xmlns="http://maven.apache.or ...

  3. vue.js在html页面中的使用

    1.加载vue.js,然后 var app = new Vue({ //vue代码})2.截图如下:

  4. 【小技巧】Eclipse 中创建Maven项目后没有WEB-INF文件夹以及web.xml文件

    懒得截图了,一张图配下面步骤搞定. 1.右键项目,选择propertities后选择图中①(被遮住了): 2.先不②勾选去掉,点击Apply:然后在把②处勾选上.此时④位置会出现东东,点击蓝色超链接. ...

  5. FreeBSD系统基本操作

    1:系统安装 2:关机与重启命令 立即关机,但是不关闭电源: shutdown -h now 立即关机,并且关闭电源: shutdown -p now 重启命令 shutdown -r now

  6. 痞子衡嵌入式:可通过USB Device Path来唯一指定i.MXRT设备进行ROM/Flashloader通信

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是通过USB Device Path来唯一指定i.MXRT设备进行ROM/Flashloader通信. i.MXRT系列高性能微控制器从2 ...

  7. 基于Gitlab的CICD流程

    本片文章主要初步介绍什么是CICD流程,并且把整个流程进行拆分理解整个流程的跑通过程. 1.CICD概述 什么是CICD呢? 简单的说CICD就是持续集成自动构建自动测试自动部署. 从概念上就可以看出 ...

  8. 消息队列RabbitMQ(二):RabbitMQ的系统架构概述

    前言 RabbitMQ是基于AMQP协议的,要想深入理解RabbitMQ,就必须先了解AMQP是个什么东东? AMQP协议 AMQP即Advanced Message Queuing Protocol ...

  9. spring总结归纳

    愿历尽千帆,归来仍是少年 简介 spring: 1.是分层的full-stack(全栈)轻量级开源框架.2. 内核:IOC和AOP.3.提供web层springMvc和业务层事务管理,整合众多的开源框 ...

  10. Linux USB ECM Gadget 驱动介绍

    ​1 USB ECM介绍 USB ECM,属于USB-IF定义的CDC(Communication Device Class)下的一个子类:Ethernet Networking Control Mo ...