热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

我所理解的JMM2new原子性

概述文本探讨构造函数是否为原子性问题。案例我们首先如下代码:publicclassPerson{publicintage;publicPerson(){age

概述

文本探讨构造函数是否为原子性问题。


案例

我们首先如下代码:

public class Person {public int age;public Person() {age=20;}
}//构造对象
public class JavaMain {public static void main(String[] args) {Person person = new Person();}
}

请问Person person = new Person();是否为原子性操作?
下图为main函数的字节码:
在这里插入图片描述
我们可以看到构建一个类大致可以分为4步骤:


  1. new指令申请堆栈空间,并且会生成一个引用放入函数的栈帧的栈顶。
  2. dup复制栈顶,那么此处会在栈顶存在两个Person堆内存地址引用.
  3. invokespecial 弹窗栈顶Person并调用初始化函数
  4. 将栈顶的剩余的Person引用弹窗复制到本地变量槽1中

可见一个构造一个对象并非原子性操作,那么这会带来哪些多线程问题?

public class JavaMain {static Person person;public static void main(String[] args) {new Thread("Thread One") {@Overridepublic void run() {super.run();person = new Person();}}.start();new Thread("Thread Two") {@Overridepublic void run() {super.run();if (person != null) {System.out.println(person.age);}}}.start();}
}

上面会发生 data race(数据竞争)情况,上面的代码在极端情况可能会输出0.

原因调用初始化函数步骤 和将栈顶引用复制回Mainperson发生了重排序。

在这里插入图片描述
解决方案一:
利用Pesronage字段使用final修饰.

public class Person {final public int age;public Person() {age = 20;}
}

关于final语义后文讲解.

其他解决方案:
1.同步锁
2.volatile修饰
3.利用happer-before关系防止重排序(volatile原理)
4. 略


推荐阅读
  • Android获取app应用程序大小的方法
    Android获取app应用程序大小的方法-Android对这种方法进行了封装,我们没有权限去调用这个方法,所以我们只能通过AIDL,然后利用Java的反射机制去调用系统级的方法。 ... [详细]
  • Java编程思想一书中第21章并发中关于线程间协作的一节中有个关于汽车打蜡与抛光的小例子(原书的704页)。这个例子主要展示的是两个线程如何通过wait ... [详细]
  • 图片添加二维码水印教程
    本博客介绍一下用jdkawt实现图片加文字水印和图片水印的方法一、图片文字水印原来图片加上文字水印后图片二、图片加图片水印原来图片:水印图片:添加水印后的图片: ... [详细]
  • 精讲代理设计模式
    代理设计模式为其他对象提供一种代理以控制对这个对象的访问。代理模式实现原理代理模式主要包含三个角色,即抽象主题角色(Subject)、委托类角色(被代理角色ÿ ... [详细]
  • java线程池的实现原理源码分析
    这篇文章主要介绍“java线程池的实现原理源码分析”,在日常操作中,相信很多人在java线程池的实现原理源码分析问题上存在疑惑,小编查阅了各式资 ... [详细]
  • WPF之Binding初探
      初学wpf,经常被Binding搞晕,以下记录写Binding的基础。首先,盗用张图。这图形象的说明了Binding的机理。对于Binding,意思是数据绑定,基本用法是:1、 ... [详细]
  • 展开全部可以用反射根据给定的类名来动态生成实例62616964757a686964616fe59b9ee7ad9431333337613839比如你定义了一个类packagesam ... [详细]
  • Java技能树易混淆概念类变量/实例变量/局部变量
    Java语言支持的变量类型有:类变量:独立于方法之外的变量,用static修饰。实例变量:独立于方法之外的变量࿰ ... [详细]
  • JVM:33 如何查看JVM的Full GC日志
    1.示例代码packagecom.webcode;publicclassDemo4{publicstaticvoidmain(String[]args){byte[]arr ... [详细]
  • Ihavebeenworkingwithbufferingafileonmylocaldrivetoparseandobtaincertaindata.Forte ... [详细]
  • 题目内容:下图为国内主要城市之间的公路里程:你的程序要读入这样的一张表,然后,根据输入的两个城市的名称,给出这两个城市之间的里程。注意:任何两个城市之间的里程都已经给出,不需要计 ... [详细]
  • 一篇博客读懂设计模式之—工厂模式工厂模式在我们日常开发的时候经常用到,相信大家都有了一定的了解,工厂模式是一种创建对象的设计模式,它提供 ... [详细]
  • PreparedStatement防止SQL注入
    添加数据:packagecom.hyc.study03;importcom.hyc.study02.utils.JDBCUtils;importjava.sql ... [详细]
  • 近来有一个需求,是需要在androidjava基础库中插入一些log信息,完成这个工作需要的前置条件有编译好的android源码具体android源码如何编译,这 ... [详细]
  • 阅读spring5源码DefaultSingletonBeanRegistry类遇到问题发现SpringBean中存在大量回调机制和aware接口,于是特意去了解 ... [详细]
author-avatar
今生绝恋2702934494
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有