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

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

正文


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


对象的创建过程


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

21.png


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

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

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

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

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


DCL与Volatile之间的纠葛


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

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

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

目录
打赏
0
0
0
0
4
分享
相关文章
Lock锁和AQS之间的关系与区别:基于第一原理的深入分析
【11月更文挑战第26天】在Java并发编程中,锁(Lock)和队列同步器(AbstractQueuedSynchronizer,简称AQS)是两个核心概念。它们为多线程环境下的同步和互斥提供了强大的支持。本文将从第一原理出发,深入探讨Lock锁和AQS之间的关系与区别,同时分析它们的相关概念、业务场景、历史背景、功能点以及底层原理,并使用Java代码进行模拟实现。
55 1
Java面试题:Java内存模型中的主内存与工作内存是如何协同工作的?请解释Java内存模型中的可见性、原子性和有序性,举例说明Java内存模型中的happens-before关系
Java面试题:Java内存模型中的主内存与工作内存是如何协同工作的?请解释Java内存模型中的可见性、原子性和有序性,举例说明Java内存模型中的happens-before关系
60 0
|
10月前
|
【专栏】Java多线程中,锁用于控制共享资源访问,确保数据一致性和正确性,锁是什么意思,有哪些分类?
【4月更文挑战第28天】Java多线程中,锁用于控制共享资源访问,确保数据一致性和正确性。本文探讨锁的概念、作用及分类:乐观锁与悲观锁、自旋锁与适应性自旋锁、公平锁与非公平锁、可重入锁和读写锁。使用锁需注意避免死锁、合理选择锁粒度及性能优化。理解锁有助于提升多线程编程的效率和稳定性。
134 0
|
10月前
|
Java并发编程学习5-对象的组合
本篇介绍一些线程安全的组合模式(包含实例封闭,Java监视器模式,线程安全性委托,客户端加锁机制)
81 1
Java并发编程学习5-对象的组合
Java并发编程学习3-可见性和对象发布
本篇介绍对象的共享之可见性和对象发布
98 2
Java并发编程学习3-可见性和对象发布
【约束布局】ConstraintLayout 屏障 Barrier 约束 ( 简介 | 屏障适用场景 | 位置说明 | 相关属性 | 可视化操作 | 代码示例 | 总结 )(一)
【约束布局】ConstraintLayout 屏障 Barrier 约束 ( 简介 | 屏障适用场景 | 位置说明 | 相关属性 | 可视化操作 | 代码示例 | 总结 )(一)
341 0
【约束布局】ConstraintLayout 屏障 Barrier 约束 ( 简介 | 屏障适用场景 | 位置说明 | 相关属性 | 可视化操作 | 代码示例 | 总结 )(一)
c++ 有趣的动态转换之 delete 崩溃探究兼谈基类虚析构的重要性
c++ 有趣的动态转换之 delete 崩溃探究兼谈基类虚析构的重要性
__weak关键字:程序模块相互独立的大杀器
__weak关键字:程序模块相互独立的大杀器
91 0
《JUC并发编程 - 高级篇》05 -共享模型之无锁 (CAS | 原子整数 | 原子引用 | 原子数组 | 字段更新器 | 原子累加器 | Unsafe类 )(三)
《JUC并发编程 - 高级篇》05 -共享模型之无锁 (CAS | 原子整数 | 原子引用 | 原子数组 | 字段更新器 | 原子累加器 | Unsafe类 )
《JUC并发编程 - 高级篇》05 -共享模型之无锁 (CAS | 原子整数 | 原子引用 | 原子数组 | 字段更新器 | 原子累加器 | Unsafe类 )(三)
《JUC并发编程 - 高级篇》05 -共享模型之无锁 (CAS | 原子整数 | 原子引用 | 原子数组 | 字段更新器 | 原子累加器 | Unsafe类 )(二)
《JUC并发编程 - 高级篇》05 -共享模型之无锁 (CAS | 原子整数 | 原子引用 | 原子数组 | 字段更新器 | 原子累加器 | Unsafe类 )
《JUC并发编程 - 高级篇》05 -共享模型之无锁 (CAS | 原子整数 | 原子引用 | 原子数组 | 字段更新器 | 原子累加器 | Unsafe类 )(二)
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等