对象的创建过程、DCL与Volatile之间的纠葛

简介: 对象的创建过程、DCL与Volatile之间的纠葛

正文


在我们写代码的过程中,我们很容易、很方便的就可以写出一个类,定义一些属性和方法。当我们使用的时候,直接新建new一个对象,或者想跳过范型检查的话,我们还可以利用反射的方式来创建我们的对象。那么在对象创建的时候,都发生了哪些事以及我们使用对象的时候,应该注意什么呢?


对象的创建过程


通常对象的对创建以及使用分为大致分为下面的几个过程:

21.png


加载:当我们进行创建对象的时候,比如使用new的时候,首先将去检查这个指令的参数是否能在常量池中定位到 一个类的符号引用,并且检查这个符号引用代表的类是否已被加载、解析和初始化过。如果没有,那必须先执行相应的类加载过程。

连接:这个过程分为三步,分别是:验证、准备以及解析。在这个过程中,Java虚拟机会进行对该对象进行空间分配,设置初值等。设置对象头,实例数据的初值,以及对齐补充数据。

初始化:在此之前,虽然Java虚拟机已经帮助我们实现了对象的空间分配以及设置默认值等操作,但是对于一些有值的属性会在初始化的时候进行赋值,也就是执行init()方法。执行完初始化的方法后,我们的对象就创建成功了,可以为以后的各个操作提供对象的实例。

使用:使用也是我们操作对象的过程。

卸载回收:使用完毕之后,Java虚拟机会自动的帮助我们将不用的对象内存进行回收。


DCL与Volatile之间的纠葛


DCL我们都知道,是我们使用懒汉式创建我们单例对象时候格式,也就是双重的检验。但是他与Volatile有什么关系呢?

我们在前面可知,在我们对象创建的连接的过程,Java虚拟机已经给我们分配了对象实例的内存大小以及地址,这个时候还没有进行初始化。初始化后,我们的对象实例就可以使用了。但是在多线程并发的时候,由于我们Java虚拟机会优化我们的指令的执行顺序,也就是指令的重排序,在单线程来看,我们的运行结果是没有问题的了。但是多线程的情况下们很有可能会发生我们的对象没有初始化就被其他的线程应用了。这就是对象逸出。

volatile的出现解决了这个问题,因为volatile可以实现指令的内存可见行以及禁止指令的重新排序。实现的方式采用的是内存屏障。有效的解决了我们前面所说的对象没有创建完就使用的情形。

相关文章
|
4月前
|
C++
成员初始化表的执行顺序与顺写顺序无关
成员初始化表的执行顺序与顺写顺序无关
27 0
|
2月前
|
Java 关系型数据库 MySQL
【数据库连接,线程,ThreadLocal三者之间的关系】
【数据库连接,线程,ThreadLocal三者之间的关系】
24 0
|
2月前
|
存储 安全 Java
|
缓存 安全 Java
《JUC并发编程 - 高级篇》05 -共享模型之无锁 (CAS | 原子整数 | 原子引用 | 原子数组 | 字段更新器 | 原子累加器 | Unsafe类 )
《JUC并发编程 - 高级篇》05 -共享模型之无锁 (CAS | 原子整数 | 原子引用 | 原子数组 | 字段更新器 | 原子累加器 | Unsafe类 )
《JUC并发编程 - 高级篇》05 -共享模型之无锁 (CAS | 原子整数 | 原子引用 | 原子数组 | 字段更新器 | 原子累加器 | Unsafe类 )
|
存储 缓存 安全
《JUC并发编程 - 高级篇》05 -共享模型之无锁 (CAS | 原子整数 | 原子引用 | 原子数组 | 字段更新器 | 原子累加器 | Unsafe类 )(三)
《JUC并发编程 - 高级篇》05 -共享模型之无锁 (CAS | 原子整数 | 原子引用 | 原子数组 | 字段更新器 | 原子累加器 | Unsafe类 )
《JUC并发编程 - 高级篇》05 -共享模型之无锁 (CAS | 原子整数 | 原子引用 | 原子数组 | 字段更新器 | 原子累加器 | Unsafe类 )(三)
《JUC并发编程 - 高级篇》05 -共享模型之无锁 (CAS | 原子整数 | 原子引用 | 原子数组 | 字段更新器 | 原子累加器 | Unsafe类 )(二)
《JUC并发编程 - 高级篇》05 -共享模型之无锁 (CAS | 原子整数 | 原子引用 | 原子数组 | 字段更新器 | 原子累加器 | Unsafe类 )
《JUC并发编程 - 高级篇》05 -共享模型之无锁 (CAS | 原子整数 | 原子引用 | 原子数组 | 字段更新器 | 原子累加器 | Unsafe类 )(二)
|
安全 Java 编译器
C++中以独立语句将new对象置入智能指针
C++中以独立语句将new对象置入智能指针
168 0
|
存储 安全 Java
Java并发编程 - 有状态 & 无状态的对象区别
Java并发编程 - 有状态 & 无状态的对象区别
563 0
|
Java 编译器
Java 线程执行与变量可见性的 happen-before 关系
happen-before 的关系是保证一个线程执行的操作结果对不同线程中的另一个操作可见。
120 0
Java 线程执行与变量可见性的 happen-before 关系
|
安全 Java
java线程同步 synchronized失效???(理解好是否上锁的是同一个对象,因为同一个对象对应的run( ) 是同一个 )
java线程同步 synchronized失效???(理解好是否上锁的是同一个对象,因为同一个对象对应的run( ) 是同一个 )
353 0
java线程同步 synchronized失效???(理解好是否上锁的是同一个对象,因为同一个对象对应的run( ) 是同一个 )