Java内存模型–快速概述和注意事项

在计算中, 内存模型描述了线程如何通过内存进行交互,或更一般地,它指定了为分段内存或分页内存平台生成代码时允许编译器进行的假设。 在给定程序和该程序的执行跟踪的情况下,它实质上描述了执行跟踪是否是该程序的合法执行。

Java内存模型描述了Java编程语言中的线程如何通过内存进行交互。 连同代码的单线程执行描述一起,内存模型提供了Java编程语言的语义。 最初的Java内存模型开发于1995年,人们普遍认为它已损坏,从而阻止了许多运行时优化,并且没有为代码安全性提供足够有力的保证。 它通过Java社区流程进行了更新,即Java规范请求133(JSR-133) (于2004年对Tiger(Java 5.0)生效)。

您可以在Java语言规范的“ 线程和锁 ”一章以及此Java内存模型讨论页面中找到一些非常有用的信息。

现在,让我们从“ The Khangaonkar Report ”中看到我们最新的JCG合作伙伴 Manoj提供的有关该主题的一些见解。

(注意:对原始帖子进行了少量编辑以提高可读性)

Java内存模型描述了定义多个线程写入和读取变量时如何看待写入内存的规则。

当线程读取变量时,它不一定从内存中获取最新值。 处理器可能返回一个缓存的值。 此外,即使程序员在编写代码时先写入变量,然后读取变量,但只要编译器不改变程序语义,就可以对语句重新排序。 处理器和编译器通常会这样做以优化性能。 结果,线程可能看不到它期望看到的值。 这可能导致难以修复并发程序中的错误。

Java编程语言提供了“ synchronized”,“ volatile”和“ final”关键字来帮助编写安全的多线程代码。 但是,由于内存模型未指定,Java的早期版本存在一些问题。 JSR 133(Java内存模型和线程规范修订版)修复了早期内存模型中的某些缺陷。

大多数程序员都熟悉这样一个事实,即进入同步块意味着在监视器上获得一个锁,以确保没有其他线程可以进入同步块。 不那么熟悉但同样重要的事实是

(1)获取锁并输入同步块会强制线程从内存刷新数据。
(2)退出同步块后,写入的数据将刷新到内存中。

这确保了同步块中的线程对同步块中的其他线程可见。

有没有听说过Java上下文中的“ 发生在……之前 ”? JSR 133引入了“之前发生”一词,并为程序中动作的顺序提供了一些保证。 这些保证是:

(1)线程中的每个动作都在该线程之后的所有其他动作之前发生。
(2)显示器上的解锁发生在同一显示器上的后续锁定之前
(3)对变量的易失性写入发生在对同一变量的后续易失性读取之前 (4)对Thread.start()的调用发生在该线程中的任何其他语句之前 (5)线程中的所有动作发生在该线程上的其他任何线程从join()返回之前

术语“动作”在Java语言规范的17.4.2节中定义为可以被其他线程检测或影响的语句。 正常的读/写,易失性的读/写,锁定/解锁是一些动作。

规则1、4和5保证在单个线程中,所有动作将按照它们在创作程序中出现的顺序执行。 规则2和4确保在处理共享数据的多个线程之间,保留同步块的相对顺序以及对易失变量的读/写顺序。

规则2和规则4使volatile非常类似于同步块。 在JSR 133之前,volatile仍然意味着对volatile变量的写操作直接写到内存中,而读操作则从内存中读取。 但是编译器可能会对非易失性读/写进行重新排序,而非易失性读/写会导致错误的结果。 在JSR 133之后无法使用。

还有一点值得注意。 这与在类的构造函数中初始化的最终成员有关。 只要构造函数正确完成执行,其他线程就可以看到最终成员而无需同步。 但是,如果您从构造函数中共享对对象的引用,则所有选择都将关闭。

提出的规范描述了线程,锁,易失性变量和数据竞争的语义。 这包括所谓的Java内存模型 。

相关文章:

  • Cajo,用Java完成分布式计算的最简单方法
  • Java最佳实践–高性能序列化
  • Java最佳实践–字符串性能和精确字符串匹配
  • Java最佳实践– Vector vs ArrayList vs HashSet
  • Java最佳实践–队列之战和链接的ConcurrentHashMap

翻译自: https://www.javacodegeeks.com/2011/02/java-memory-model-quick-overview-and.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/374850.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

6-7 统计某类完全平方数 (20 分)

本题要求实现一个函数,判断任一给定整数N是否满足条件:它是完全平方数,又至少有两位数字相同,如144、676等。 函数接口定义: int IsTheNumber ( const int N );其中N是用户传入的参数。如果N满足条件,则该…

C#中数组、ArrayList和List三者的区别(转) ,加修改

在C#中数组&#xff0c;ArrayList&#xff0c;List都能够存储一组对象&#xff0c;那么这三者到底有什么样的区别呢。 数组 数组在C#中最早出现的。在内存中是连续存储的&#xff0c;所以它的索引速度非常快&#xff0c;而且赋值与修改元素也很简单。 <span style"font…

phpmyadmin mysql Access denied for user 'root'@'localhost'问题解决

centos6.4 32位的vps上装了lnmp以后&#xff0c;phpmyadmin无法连接mysql服务器&#xff0c;ssh命令行里mysql -uroot -p 命令后老是出现拒绝连接的情况。php程序里也是拒绝连接。尝试过修改phpmyadmin的config.inc.php文件&#xff0c;尝试过修改my.cnf文件&#xff0c;尝试过…

带有Spring和Maven教程的JAX–WS

Spring框架通过JAX-WS提供对Web服务的远程支持&#xff0c;实际上&#xff0c;如Spring 参考文档中所述 &#xff0c;有三种将Spring POJO服务公开为JAX-WS Web服务的方式&#xff1a; 公开基于Servlet的Web服务&#xff08;适用于Java EE 5环境&#xff09; 导出独立的Web服…

7-2 然后是几点 (15 分)

7-2 然后是几点 (15 分) 有时候人们用四位数字表示一个时间&#xff0c;比如 1106 表示 11 点零 6 分。现在&#xff0c;你的程序要根据起始时间和流逝的时间计算出终止时间。 读入两个数字&#xff0c;第一个数字以这样的四位数字表示当前时间&#xff0c;第二个数字表示分钟…

CXF学习(2) helloworld

0.新建一个项目取名wsserver. pom.xml 文件如下 <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd…

Hive 接口介绍(Web UI/JDBC)

Hive 接口介绍&#xff08;Web UI/JDBC&#xff09; 实验简介 本次实验学习 Hive 的两种接口&#xff1a;Web UI 以及 JDBC。 一、实验环境说明 1. 环境登录 无需密码自动登录&#xff0c;系统用户名shiyanlou&#xff0c;密码shiyanlou 2. 环境介绍 本实验环境采用带桌面的Ubu…

Java最佳实践– Char到Byte和Byte到Char的转换

在使用Java编程语言时&#xff0c;我们将继续讨论与建议的实践有关的系列文章&#xff0c;我们将讨论String性能调优。 特别是&#xff0c;我们将重点介绍使用默认编码时如何有效地处理字符到字节和字节到字符的转换。 本文总结了两种提议的自定义方法与两种经典方法&#xff0…

IOS-C文件的创建于初始化函数.void init() write_file()

//文件初始化 void init(){ FILE * fpNULL; fpfopen("telbook.data", "rb"); int count0; if (fpNULL) //没有这个文件就把这个文件创建出来 { fpfopen("tellbook.data", "wb"); fwrite(&count, sizeof(count), 1, fp); fclose(…

7-3 逆序的三位数 (10 分)

7-3 逆序的三位数 (10 分) 程序每次读入一个正3位数&#xff0c;然后输出按位逆序的数字。注意&#xff1a;当输入的数字含有结尾的0时&#xff0c;输出不应带有前导的0。比如输入700&#xff0c;输出应该是7。 输入格式&#xff1a; 每个测试是一个3位的正整数。 输出格式&a…

抛弃优启Grub4dos和PE大多数时间可以这样用

抛弃优启Grub4dos和PE大多数时间可以这样用 在能够进入Windows的情况下&#xff0c;Grub4dos和PE大多数时间可以这样用 http://yunpan.cn/cyuuUtUQMfmGN 提取码 c2acGrub4dos的出现颠覆了传统的EZBOOT光盘启动模式&#xff0c;很多人用grub4dos来实现优盘启动&#xff0c;同时g…

Java最佳实践–队列之战和链接的ConcurrentHashMap

在使用Java编程语言时&#xff0c;我们将继续讨论与建议的实践有关的系列文章&#xff0c;我们将在四个具有相关语义的流行Queue实现类之间进行性能比较。 为了使事情变得更现实&#xff0c;我们将在多线程环境下进行测试&#xff0c;以讨论和演示如何将ArrayBlockingQueue &am…

HDU 5652 India and China Origins(二分 + BFS)

本文链接:http://www.cnblogs.com/Ash-ly/p/5398867.html 题意&#xff1a; 中国和印度之间有一片地方&#xff0c;把这片地方抽象化&#xff0c;于是就可以看成一个N * M矩阵&#xff0c;其中黑色的代表高山不能走过去&#xff0c;白色的代表平原&#xff0c;可以通行,人每次可…

C语言%.2f四舍五入

#include <stdio.h> int main() {double d 1.199;printf("%.2f", d);return 0; }输出1.20 如果不想让其四舍五入可以这样&#xff1a; #include <stdio.h> #include <math.h> int main() {double d 1.199;printf("%.2f", floor(d * 1…

关于使用racthet的push.js

racthet的push是用来跳转另外一个页面的效果的。但是必须在服务器的环境下支持。如果想要让本地html访问支持的话需要添加 转载于:https://www.cnblogs.com/djawh/p/4623925.html

休眠自动提交命令强制MySQL在过多的磁盘I / O中运行

亲爱的大家&#xff0c; 我敢肯定&#xff0c;你们中的许多人都在使用Hibernate和MySQL&#xff0c;我自己在这里和那里都使用它。 通常&#xff0c;编程模型是不错的&#xff0c;但是普通的JDBC可以快很多已经不是什么秘密了。 在这篇文章中&#xff0c;我想引起您的注意Hibe…

“应用程序无法正常启动(oxc000007b)”解决方案

解决方案1 通过“DirectX修复工具 V3.3 标准版”软件修复。 备注&#xff1a;经过测试&#xff0c;并未解决本人的问题&#xff0c;但是这个方法可能对游戏中缺失相关.dll&#xff08;动态链接库&#xff09;有帮助。 解决方案2&#xff1a; 该问题的出现不适偶然&#xff0c;主…

Linux: dev: cmake: CHECK_LIBRARY_EXISTS

文章目录 简介例子源代码最终调用到的两个命令如果结果是这里为什么不直接使用rpm查看包呢&#xff1f;需要注意的问题 简介 https://cmake.org/cmake/help/latest/module/CheckLibraryExists.html 这个方法是在Modules/CheckLibraryExists.cmake文件里定义的一个宏。 最终使用…

7-15 计算圆周率 (15 分)

根据下面关系式&#xff0c;求圆周率的值&#xff0c;直到最后一项的值小于给定阈值。 输入格式&#xff1a; 输入在一行中给出小于1的阈值。 输出格式&#xff1a; 在一行中输出满足阈值条件的近似圆周率&#xff0c;输出到小数点后6位。 输入样例&#xff1a; 0.01结尾无…

Struts2的全局结果视图的配置

1.在struts.xml中的package标签内添加<global-results/>标签&#xff0c;将全局结果加进该标签内&#xff0c;只适用于当前包下。 <package name"customer" namespace"/customer" extends"struts-default" > <global-results>…