在阅读有关内存一致性错误的Java文档时.我找到了与两个创造事件相关的点 - 在关系之前:
当一个语句调用时Thread.start(),与该语句有一个before-before关系的每个语句也与新线程执行的每个语句都有一个before-before关系.新线程可以看到导致创建新线程的代码的影响.
当一个线程终止并导致Thread.join()另一个线程返回时,终止
线程执行的所有语句
与成功连接后的所有语句都有一个before-before关系.现在,执行连接的线程可以看到线程中代码的效果.
我无法理解他们的意思.如果有人用一个简单的例子解释它会很棒.
C#和Java都定义
*volatile读取具有获取语义
*volatile写入具有发布语义
我的问题是:
- 这是定义volatile的唯一正确方法吗?
- 如果没有,如果语义被颠倒,事情就会大不相同,也就是说
- volatile读取具有释放语义
- volatile写入具有获取语义
我一直在阅读有关Java内存模型的信息,并且我知道编译器可以重新组织语句来优化代码。
假设我有以下代码:
long tick = System.nanoTime();
function_or_block_whose_time_i_intend_to_measure();
long tock = System.nanoTime();
Run Code Online (Sandbox Code Playgroud)
编译器是否会以我想要测量的方式在tick和tock之间不执行的方式重组代码?例如,
long tick = System.nanoTime();
long tock = System.nanoTime();
function_or_block_whose_time_i_intend_to_measure();
Run Code Online (Sandbox Code Playgroud)
如果是这样,保留执行顺序的正确方法是什么?
编辑:示例说明了用nanoTime乱序执行:
public class Foo {
public static void main(String[] args) {
while (true) {
long x = 0;
long tick = System.nanoTime();
for (int i = 0; i < 10000; i++) { // This for block takes ~15sec on my machine
for (int j = 0; j < 600000; j++) {
x = x + x * x; …Run Code Online (Sandbox Code Playgroud) 由于许多误解,我从头开始重新阐述了这个问题。提问的初衷没有改变。许多评论仍然引用旧的问题文本。
有关文档volatile指出,它确保其他线程以一致的方式看到内存更新。然而,volatile很少使用。
据我所知,synchronized块的目的是使线程不同时执行这些关键部分。是否也会synchronized像其他线程一样导致一致的内存更新volatile?