|
|
1
5
在java内存模型中?不,你不好。 我见过很多人试图采用这种非常“软刷新”的方法,但如果没有明确的围栏,你肯定是在玩火。 中的“before”语义 http://java.sun.com/docs/books/jls/third_edition/html/memory.html#17.7 在17.4.2末尾,开始将纯粹的线程间操作称为“操作”。这导致了很多混乱,因为在此之前,它们区分线程间和线程内的操作。因此,操作计数器的线程内操作没有通过“发生在之前”关系在易失性操作之间显式同步。关于同步,您需要遵循两个推理线程,一个线程控制本地一致性,并遵循别名分析的所有技巧,等等,以洗牌操作;另一个线程是关于全局一致性的,仅为线程间操作定义。 一个用于线程内逻辑,表示在线程内读取和写入一致地重新排序;另一个用于线程间逻辑,表示诸如易失性读取/写入以及同步开始/结束被适当地隔离。 问题是非易失性写入的可见性未定义,因为它是线程内操作,因此不在规范中涵盖。当您连续执行这些语句时,其运行的处理器应该能够看到它,但其线程间顺序可能尚未定义。 现在,这是否会影响你的现实完全是另一回事。 在x86和x86-64平台上运行java时?从技术上讲,您处于一个模糊的领域,但实际上x86对读写操作的强大保证,包括访问cacheflush时读/写操作的总顺序,以及两次写操作和两次读操作的本地顺序,应该能够使此代码正确执行,前提是它能够通过编译器而不受干扰。这假设编译器没有介入并尝试使用标准允许的自由对您的操作重新排序,因为可以证明两个线程内操作之间没有别名。 如果移动到释放语义较弱的内存(如ia64)?那你就自己回来了。 然而,编译器完全可以在任何平台上用java破坏这个程序。它现在的功能是标准当前实现的产物,而不是标准的产物。 另一方面,在CLR中,运行时模型更强大,而且这种技巧是合法的,因为来自每个线程的各个写操作都具有有序的可见性,因此请小心尝试从中翻译任何示例。 |
|
|
2
1
嗯,我想不是。 第一个if语句:
不访问任何易失性字段且未同步。因此,您可能会永远读取过时的数据,而永远不会访问volatile字段。 引用第二篇博文中的一条评论:“线程A在写入易失性字段f时可以看到的任何内容,在线程B读取f时都可以看到。” |
|
|
ron burgundy · 获取-释放语义是否跨线程传递?[副本] 1 年前 |
|
|
H3007 · 并发运行python子进程似乎不是并发的 2 年前 |
|
|
The Oddler · TVar会阻止读取直到更改吗? 2 年前 |
|
|
Wang Tuma · 使用信号量的c++并发问题:按顺序打印 2 年前 |
|
|
Marcel Batista · 在不同线程中更新密钥时的字典线程安全 2 年前 |
|
|
rico · 当volatile关键字真的是必要的? 2 年前 |