以下是经典Concurency in Practice的内容:

When thread A writes to a volatile variable and subsequently thread B

reads the same variable, the values of all variables that were

visible to A prior to writing to the volatile variable, become visible

to B after reading the volatile variable.

我不确定我是否真的能理解这一说法。 例如,在这种情况下,所有变量的含义是什么? 这是否意味着使用volatile也会对非易失性变量的使用产生副作用?

在我看来,这种说法具有我无法理解的一些微妙含义。

有什么帮助吗?

您的问题的答案在JLS#17.4.5中:

A write to a volatile field (§8.3.1.4) happens-before every subsequent read of that field.

所以如果在一个线程中

aNonVolatileVariable = 2 //w1

aVolatileVariable = 5 //w2

然后在另一个线程中:

someVariable = aVolatileVariable //r1

anotherOne = aNonVolatileVariable //r2

您可以保证anotherOne等于2,即使该变量不是volatile。因此,是的,使用volatile对使用非易失性变量也有副作用。

更详细地说,这是由于同一部分中的Java内存模型(JMM)提供了2个其他保证:线程内顺序和可传递性(hb(x,y)表示x发生在y之前):

If x and y are actions of the same thread and x comes before y in program order, then hb(x, y).

[...]

If hb(x, y) and hb(y, z), then hb(x, z).

在我的示例中:

hb(w1,w2)和hb(r1,r2)(线程内语义)

hb(w2,r1)由于易失性保证

因此您可以通过传递性得出hb(w1,r2)的结论。

而且,JMM保证,如果程序与事前发生的关系正确同步,则该程序的所有执行将保持顺序一致(即,看起来好像什么都没有重新排序)。因此,在这种特定情况下,非易失性读取可确保看到非易失性写入的效果。

很抱歉,我无法从JSL的语句中看到这种保证,它只表示对volatile happens-before的写操作读取了该字段,这又如何保证在另一个线程中< x6>可见为2?

到目前为止,我理解hb(w1, r2) .Ok,但是为??什么在这里强制要求2的更新值可见?难道是,写入发生在之前,但是读取使用了一个缓存值而不是该值从w1开始?这是我无法获得的部分。hb(w1, r2)的定义是否还包括可见性方面?

@Cratylus JMM保证正确同步的程序(具有先发生的关系)将保持顺序一致:"对于程序员,这是极其有力的保证。[...]一旦确定代码正确同步,程序员不必担心重新排序会影响他或她的代码。"

@Cratylus在同一部分中,JLS的另一句话是:"在一组一致的动作之前发生的情况下,每次读取都会看到一个写,该顺序允许在顺序发生之前看到它。"

这些说明不能解决由于重新排序而导致的不可见性吗?不会进行重新排序,但是如何在寄存器中缓存值呢?

@Cratylus"顺序一致"保证可见性。这是另一个引言(17.4.3):"顺序一致性是对程序执行中的可见性和顺序的非常有力的保证。在顺序一致的执行中,所有单个动作(例如读写),这与程序的顺序是一致的,并且每个动作都是原子的,每个线程都可以立即看到。"

这意味着如果您要写入10个非易失性变量并写入易失性变量,则必须在易失性变量之前设置所有非易失性变量。

如果您读取了volatile变量和所有非易失性变量,则可以确保订单不会被交换。

你在说什么顺序?volatile变量不能重新排序,好,所以volatile变量不应该用非易失性重新演算并最后写入,但是非易失性变量的顺序可以还可以改变吧?

在易失性变量中设置的值的顺序不能相对于其他变量(易失性或其他)更改,但是对于非易失性变量可能会发生这种情况。这意味着,当您设置易失性变量时,所有先前设置的值即使不是易失性的,也会被设置为缓存连贯的。

什么是缓存一致性?它们也不会被缓存?

它们将被缓存,但是CPU确保每个缓存看到相同的值(或将按需请求)。每个套接字具有2个或3个级别的多个缓存。它们具有通信总线,以确保它们在需要时彼此同步。甚至多个套接字也会通信以保持同步,从而避免了必须从主存储器中写入/读取值的情况。

但是为什么非易失性变量需要并保证这种同步呢,仅仅因为它们恰好是在写入volatile之前发生的,它们如何受到影响?

同步以一致的方式提供了更多的保证,例如读取和写入,例如增量。仅阅读或写作通常不是您所需要的。 volatile的定义使得在它之前发生的所有写入都不得在它之后发生。

all writes which occur before it must not occur after it。我理解这一点,但这如何取决于/对缓存一致性产生副作用?这是我不关注的部分

我认为这里有些混乱。我见过很多人评论说,volatile关键字会影响第一级和第二级缓存等的处理器缓存一致性。我不知道这怎么可能是正确的。一方面,高速缓存一致性协议可确保同一内存位置的多个线程视图始终保持同步。 VM更有可能为每个线程维护一个单独的内存缓存区域,而volatile关键字调用一些用于同步它们的代码。

JVM仅使用执行高速缓存一致性读取和写入的指令或不执行高速缓存一致性的简单读取和写入的指令。它不执行CPU本身不支持的任何操作。此外,JVM可以优化非易失性字段的读取方式,这意味着它们永远不会看到更新,因为它们不会在同一线程中被更改。

彼得,我的意思是,我不认为您所指的缓存与处理器缓存相同。而是由VM维护的缓存。换句话说,如果两个线程读取两个不同的值,则它们正在从两个不同的内存地址读取。如果两个线程从同一地址读取,则处理器缓存一致性协议将保证它们都接收相同的值。那是我的理解。如果我错了,那么我想知道。

VM不维护此类缓存。当您从两个不同的缓存中读取相同的地址时,可以获得不同的值。并非对所有CPU指令都强制执行缓存一致性。

java 易变变量_关于java:易变变量和其他变量相关推荐

  1. java项目----教务管理系统_基于Java的教务管理系统

    java项目----教务管理系统_基于Java的教务管理系统 2022-04-22 18:18·java基础 最近为客户开发了一套学校用教务管理系统,主要实现学生.课程.老师.选课等相关的信息化管理功 ...

  2. 开发java程序的步骤_开发 Java 程序的一般步骤是:源程序编辑、 和 。_学小易找答案...

    [多选题]财务报表分析具有广泛的用途,一般包括( ). [单选题]在财务报表分析中,投资人是指( ). [单选题]阅读下列代码,选出该代码段正确的文件名( ). class A{ void metho ...

  3. java蓝桥杯加法变乘法_蓝桥杯-加法变乘法-java

    /* (程序头部注释开始) * 程序的版权和版本声明部分 * Copyright (c) 2016, 广州科技贸易职业学院信息工程系学生 * All rights reserved. * 文件名称: ...

  4. 安装java 并配置环境变量_安装Java JDK并配置环境变量

    学习JAVA,必须得安装一下JDK(java development kit java开发工具包),配置一下环境就可以学习JAVA了,下面是下载和安装JDK的教程: 点开链接你应该看到如下图所示的界面 ...

  5. macbook配置java环境变量_配置java环境变量

    1.找到此电脑我的电脑右键属性. 2.点击高级系统设置. 3.点击环境变量. 4.点击新建. 5.创建变量名JAVA_HOME必须是大写,变量值找到你的jdk的根目录复制下来,然后粘贴进去,点击确定. ...

  6. java设置系统环境变量_设置java 环境变量

    DOS下任意目录用JAVA,JAVAC肯定是显示正确咯,因为你设置好了JAVAlib和bin的但是JAVA文件需要DOS下CD好了目录才能JAVAC否则是在C:\program里查找该JAVA文件你任 ...

  7. 环境变量_配置JAVA环境变量

    本文标识 :  J00001本文编辑 :  YiKi编程工具 :  IDEA阅读时长 :  3分钟 什么是环境变量?环境变量是在操作系统中一个具有特定名字的对象, 它包含了一个或者多个应用程序所将使用 ...

  8. java gui变量_关于java:静态/类变量和GUI

    本问题已经有最佳答案,请猛点这里访问. 最近,我被拉回到了Java编程的学术目的,我遇到了一些有趣的在我的第一个项目. 我必须为一个店面设计一个图形用户界面,其中有执行各种任务的按钮,我注意到我的变量 ...

  9. java打印星型_初识java java入门知识 基础知识 打印各种星型图形 源代码

    今天给大家带来的是初级Java基础部分的知识:包括初识Java.变量.常量.数据类型.运算符.各种选择结构.循环结构.数组等Java的基础语法部分!最后还有****循环结构的进阶****,步骤超详细, ...

最新文章

  1. sql server 2000 版本查询
  2. 插值算法及matlab实现,MATLAB 插值算法实现
  3. Linux基础学习三:VMware和CentOS的安装详细图文教程
  4. linux下mongo工具,linux – 从另一台机器上使用mongodb工具(mongodump,mongorestore)
  5. 汪学明导师—商业模式创新与转型专家
  6. 黑白群晖为Plex添加证书,开启HTTPS访问
  7. 【LINUX C 写文件】
  8. 微型计算机初级证书,什么是计算机初级证书
  9. UiAutomator2—By、BySelector
  10. BP神经网络回归预测模型(python实现)
  11. 详细理解TDMA以及OFDMA,更容易读懂论文
  12. python:判断3个数不相等
  13. 显示如何用最少的20美元来付款
  14. 本质矩阵与基本矩阵(Essential and Fundamental Matrices)
  15. 移动APP导航栏设计对比
  16. vue移动端,使用腾讯提供的JS SDK实现第三方登录
  17. ssd用在无盘服务器,无盘服务器用ssd
  18. Linux内核MTD子系统七之Flash 存储器接口标准:CFI和JEDEC
  19. MongoDb数组操作 - unwind解包、group分组统计、sort排序
  20. 小程序对接停车场支付流程思考

热门文章

  1. lru调度算法例题_嵌入式必会!C语言最常用的贪心算法就这么被攻略了
  2. 计算机组成原理和体系结构----软考(到处copy)
  3. 深入了解EntityFramework——数据注解属性
  4. Linux系统的服务器配置minicom接console线调试交换机的步骤
  5. 代码合并工具_分享几款比较常用的代码比较工具
  6. c 语言 abs 库函数,absread,abswirte - C 语言库函数手册
  7. oracle ora31633,ORA-31633: unable to create master table
  8. 修改所有列_哪些数据库是行存储?哪些是列存储?有什么区别?
  9. python与javascript的区别_python与js区别有哪些
  10. html如何让图片跟字体重叠,CSS设置图片与文字的间距