public class Main {
private int x;
private volatile int g;
public void actor1(){
x = 1;
g = 1;
}
public void actor2(){
put_on_screen_without_sync(g);
put_on_screen_without_sync(x);
}
}
.................(I removed not important body of method).....
0x00007f42307d9d5e: c7460c01000000 (1) mov dword ptr [rsi+0ch],1h
;*putfield x
; - package.Main::actor1@2 (line 14)
0x00007f42307d9d65: bf01000000 (2) mov edi,1h
0x00007f42307d9d6a: 897e10 (3) mov dword ptr [rsi+10h],edi
0x00007f42307d9d6d: f083042400 (4) lock add dword ptr [rsp],0h
;*putfield g
; - package.Main::actor1@7 (line 15)
0x00007f42307d9d72: 4883c430 add rsp,30h
0x00007f42307d9d76: 5d pop rbp
0x00007f42307d9d77: 850583535116 test dword ptr [7f4246cef100h],eax
; {poll_return}
0x00007f42307d9d7d: c3 ret
int tmp = i; // volatile load
// [LoadStore]
// [LoadLoad]
// [StoreLoad] -- this one
int tmp = i; // volatile load
// [LoadStore]
// [LoadLoad]
需要有一个连续的一致性
但是,我不明白为什么要有顺序的一致性。
首先,将被刷新到内存
-这是非常错误的。它几乎从来没有冲过主内存--它通常会将StoreBuffer排空到L1
,并且由缓存一致性协议来同步所有缓存之间的数据,但如果您更容易理解这个概念,那么它也很好--只需知道这一点略有不同且速度更快。
这是一个很好的问题,为什么[StoreLoad]
会出现在那里,也许这会让事情变得更清楚一些。volatile
实际上都是关于栅栏的,下面是一个示例,说明在执行某些volatile操作时会插入哪些屏障。例如,我们有一个volatile load
:
// i is some shared volatile field
int tmp = i; // volatile load of "i"
// [LoadLoad|LoadStore]
请注意LoadStore
和LoadLoad
中的两个障碍;简而言之,它意味着在volatile load/read
之后的任何load
和store
都不能“上移”屏障,它们不能在volatile load的“上方”重新排序。
// "i" is a shared volatile variable
// [StoreStore|LoadStore]
i = tmp; // volatile store
// any store of some other volatile
// can not be reordered with this volatile load
// [StoreLoad] -- this one
int tmp = i; // volatile load of a shared variable "i"
// [LoadStore|LoadLoad]
// [StoreStore|LoadStore]
i = tmp; // volatile store
// [StoreLoad] -- and this one
假设您有这样的情况:
[StoreStore|LoadStore]
int x = 4; // volatile store of a shared "x" variable
int y = 3; // non-volatile store of shared variable "y"
int z = x; // volatile load
[LoadLoad|LoadStore]
基本上不存在阻止volatile store
与volatile load
重新排序的障碍(即:首先执行volatile load),这显然会引起问题;从而违反顺序一致性。
顺便说一句(如果我没有搞错的话),通过在volatile load可见之前,不会对volatile load之后的每一个操作进行重新排序
您有点错过了这一点。volatile本身不可能重新排序-其他操作可以自由重新排序。我给大家举个例子:
int tmp = i; // volatile load of a shared variable "i"
// [LoadStore|LoadLoad]
int x = 3; // plain store
int y = 4; // plain store
int tmp = i; // volatile load
// [LoadStore|LoadLoad]
// see how they have been inverted here...
int y = 4; // plain store
int x = 3; // plain store
问题内容: 我写这篇文章与深入了解Java中的volatile有关 现在,我正在分析JIT为上面的代码生成的内容。从上一篇文章的讨论中,我们知道输出是不可能的,因为: 写挥发的原因,每一个动作前述原因,那之前是可见的(将被刷新到内存)将是可见的。 我是否正确理解它可以工作,因为x86无法重新排序?如果可以,则需要附加的内存屏障,是吗? 优秀@Eugene的答案后编辑: 在这里,我明白您的意思了-很
如果你使用了 vux2 模板或者 webpack 模板,默认你可以直接通过判断 process.env.NODE_ENV 来区分 比如统计代码仅放在 production 环境,在不同环境里使用不同的 API 接口地址。 if (process.env.NODE_ENV === 'production') { // 干一些线上才要做的事情 } if (process.env.NODE_ENV
标签(空格分隔): EBOOKCHAIN PM2 NODEJS [TOC] 前言 部署前请先安装Ebookcoin 请参考官方wiki:https://github.com/Ebookcoin/ebookcoin/wiki/ pm2简介 Node.js默认单进程运行,对于32位系统最高可以使用512MB内存,对于64位最高可以使用1GB内存。对于多核CPU的计算机来说,这样做效率很低,因为只有一个
本文向大家介绍linux环境下java程序打包成简单的hello world输出jar包示例,包括了linux环境下java程序打包成简单的hello world输出jar包示例的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了linux环境下java程序打包成简单的hello world输出jar包。分享给大家供大家参考,具体如下: 1. linux必须已安装java环境,测试 说明j
我目前正在学习多线程,我发现了一些我无法解释的有趣的东西。据我所知,如果两个线程访问一个静态变量,它们可以将自己的副本复制到缓存中。Thread1对其本地缓存中的静态变量进行的更新不会反映在Thread2缓存的静态变量中。 java java