Java内存模型和优化
总览
许多多线程代码开发人员都熟悉这样的想法,即不同的线程可以对持有的值有不同的看法,这不是唯一的原因,即如果线程不安全,它可能不会看到更改。 JIT本身可以发挥作用。
为什么不同的线程看到不同的值?
当您有多个线程时,它们将尝试例如通过尝试访问同一内存来最小化它们将交互的数量。 为此,他们有一个单独的
本地副本,例如在1级缓存中。 该缓存通常最终是一致的。 我看到两个线程看到不同值的短时间介于一微秒到十毫秒之间。 最终,线程被上下文切换,缓存被清除或更新。 无法保证何时会发生这种情况,但几乎总是不到一秒钟。
JIT如何发挥作用?
Java内存模型说,不能保证不是线程安全的字段将看到更新。 这允许JIT进行优化,将仅读取而不写入的值有效地内联到代码中。 这意味着即使更新了缓存,更改也可能不会反映在代码中。
一个例子
该代码将一直运行,直到将布尔值设置为false为止。
>static class MyTask implements Runnable {private final int loopTimes;private boolean running = true;boolean stopped = false;public MyTask(int loopTimes) {this.loopTimes = loopTimes;}@Overridepublic void run() {try {while (running) {longCalculation();}} finally {stopped = true;}}private void longCalculation() {for (int i = 1; i < loopTimes; i++)if (Math.log10(i) < 0)throw new AssertionError();}
}public static void main(String... args) throws InterruptedException {int loopTimes = Integer.parseInt(args[0]);MyTask task = new MyTask(loopTimes);Thread thread = new Thread(task);thread.setDaemon(true);thread.start();TimeUnit.MILLISECONDS.sleep(100);task.running = false;for (int i = 0; i < 200; i++) {TimeUnit.MILLISECONDS.sleep(500);System.out.println("stopped = " + task.stopped);if (task.stopped)break;}
}
此代码反复执行一些对内存没有影响的工作。 它唯一的区别是需要多长时间。 通过花费更长的时间,它将确定在运行之前或之后将run()中的代码优化为false。
如果我使用10或100和-XX:+ PrintCompilation运行此命令,则会看到
111 1 java.lang.String::hashCode (55 bytes)
112 2 java.lang.String::charAt (29 bytes)
135 3 vanilla.java.perfeg.threads.OptimisationMain$MyTask :longCalculation (35 bytes)
204 1 % ! vanilla.java.perfeg.threads.OptimisationMain$MyTask :run @ 0 (31 bytes)
stopped = false
stopped = false
stopped = false
stopped = false
... many deleted ...
stopped = false
stopped = false
stopped = false
stopped = false
stopped = false
如果我用1000运行它,您会看到run()尚未编译并且线程停止
112 1 java.lang.String::hashCode (55 bytes)
112 2 java.lang.String::charAt (29 bytes)
133 3 vanilla.java.perfeg.threads.OptimisationMain $MyTask::longCalculation (35 bytes)
135 1 % vanilla.java.perfeg.threads.OptimisationMain $MyTask::longCalculation @ 2 (35 bytes)
stopped = true
一旦线程被编译,即使线程将进行多次上下文切换等,更改也永远不会被看到。
如何解决这个问题
简单的解决方案是使该字段易变。 这将确保该字段的值是一致的,而不仅仅是最终一致的,这就是缓存可能为您执行的操作。
结论
虽然有许多类似的问题示例; 为什么我的线程没有停止? 答案更多与Java内存模型有关,Java内存模型允许JIT“内联”它执行硬件的字段,并在不同的缓存中具有多个数据副本。
参考: Vanilla Java博客上的JCG合作伙伴 Peter Lawrey提供的Java内存模型和优化 。
翻译自: https://www.javacodegeeks.com/2013/01/java-memory-model-and-optimisation-2.html
Java内存模型和优化相关推荐
- java内存模型和内存结构_Java内存模型和优化
java内存模型和内存结构 总览 许多多线程代码开发人员都熟悉这样的想法,即不同的线程可以对持有的值有不同的看法,这不是唯一的原因,即如果线程不安全,它可能不会看到更改. JIT本身可以发挥作用. 为 ...
- 从底层吃透java内存模型(JMM)、volatile、CAS
前言 随着计算机的飞速发展,cpu从单核到四核,八核.在2020年中国网民数预计将达到11亿人.这些数据都意味着,作为一名java程序员,必须要掌握多线程开发,谈及多线程,绕不开的是对JMM(Java ...
- 循序渐进:带你理解什么是Java内存模型
近期笔者在阅读<深入理解Java虚拟机:JVM高级特性与最佳实现(第3版)>,书中提到关于Java内存模型的知识点,但是看完之后还是感觉有些模糊,便查阅一些其他相关资料.本文是笔者经过对知 ...
- JSR 133 Java内存模型以及并发编程的最权威论文汇总
Java内存模型 先看官方文档: https://docs.oracle.com/javase/specs/ JSR 133:Java TM内存模型和线程规范修订版:https://www.jcp.o ...
- java线程的优先级是数字越大优先级越高_《深入理解Java虚拟机》5分钟速成:12章(Java内存模型与线程)...
第12章 Java内存模型与线程 前言: 1.物理机如何处理并发问题? 2.什么是Java内存模型? 3.原子性.可见性.有序性的具体含义和应用实现? 4.volatile 关键字特性? 5.基于vo ...
- Java内存模型与线程
一.一致性 高速缓存的存储交互很好的解决了处理器与内存的速度矛盾,但也存在缓存一致性(cache coherence)问题 二.java内存模型 内存模型:对特定的内存或高速缓存进行读写访问的过程抽象 ...
- 深入理解Java内存模型(四)——volatile
2019独角兽企业重金招聘Python工程师标准>>> volatile的特性 当我们声明共享变量为volatile后,对这个变量的读/写将会很特别.理解volatile特性的一个好 ...
- 也许,这是东半球最叼的Java内存模型
面试官:你好,你先自我介绍一下. 安琪拉:面试官你好,我叫安琪拉,草丛三婊,最强中单,草地摩托车车手,第21套广播体操推广者,火球拥有者.不焚者,安琪拉,这是我的简历,请过目. 面试官:看你简历上写熟 ...
- 并发编程专题——第一章(深入理解java内存模型)
说到并发编程,其实有时候觉得,开发中真遇到这些所谓的并发编程,场景多吗,这应该是很多互联网的在职人员,一直在考虑的事情,也一直很想问,但是又不敢问,想学习的同时,网上这些讲的又是乱七八糟,那么本章开始 ...
最新文章
- C#利用Graphics类绘制进阶--实现图片等比例缩放
- 人类首次商业太空行走敲定!马斯克SpaceX宣布新一轮太空旅行计划,美国富豪成回头客...
- 二、MySql优化七个查询命令特征
- windows编程,服务器与客户端
- 获取顶级常量、祖先链、私有方法
- [Qt教程] 第15篇 2D绘图(五)绘制图片
- [蓝桥杯2016决赛]一步之遥-枚举
- qt 中使用openssl_openSSL漏洞致使SSL证书安全配置评级F
- JAVA 简单的抽奖程序
- 嵌入式开发有年龄限制吗_报名深圳成考有年龄限制吗?
- 使用wampserver部署的织梦站点无法登录后台
- LeetCode 第 69 场力扣双周赛
- Prototype使用$F()函数
- sql plus命令大全(2)
- 电脑硬件故障排除经验
- python电话簿_python 联系簿
- 2019念念不忘,2020必有回响!!!
- (原创)C# LRC复读机-1
- php共享汽车怎么扫码开车,共享汽车套路真多!看完恍然大悟
- 如何制作SSL证书即https服务支持
热门文章
- 布隆过滤器速度_详解布隆过滤器的原理、使用场景和注意事项
- 算法设计与分析:(二)动态规划
- java登录界面命令_Java命令行界面(第10部分):picocli
- spring 启动进度_在Web浏览器中显示Spring应用程序启动的进度
- 声明式编程与函数式编程_实用程序类与函数式编程无关
- 使用适用于Java 2的AWS开发工具包的AWS DynamoDB版本字段
- Java 8 Stream中间操作(方法)示例
- javafx_JavaFX技巧4:总结
- Selenium WebDriver中的TestNG侦听器及示例
- akka2.5_发布Akka Toolkit 2.3