Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 读取易失性变量是否会影响线程缓存中其他非易失性变量的值?_Java_Multithreading_Volatile - Fatal编程技术网

Java 读取易失性变量是否会影响线程缓存中其他非易失性变量的值?

Java 读取易失性变量是否会影响线程缓存中其他非易失性变量的值?,java,multithreading,volatile,Java,Multithreading,Volatile,为什么以下代码可以停止线程1?读取易失性变量是否会影响线程缓存中其他非易失性变量的值?当线程1读取“s”时,它也将重新加载新值“run” }Java内存模型(JMM)定义了一些保证。除了这些保证,虚拟机可以自由地做任何他们想做的事情。因此,通常情况下,对这样一个问题的答案是:“这里是否可能刷新缓存?”是是,因为你应该问更多的绝对主义问题:“这里是否保证刷新缓存?”这是一个更有趣的问题 JMM基于“发生在之前/之后”的概念。JMM定义了一些特定的场景,在这些场景中,JMM将保证代码的执行,从而使您

为什么以下代码可以停止线程1?读取易失性变量是否会影响线程缓存中其他非易失性变量的值?当线程1读取“s”时,它也将重新加载新值“run”

}Java内存模型(JMM)定义了一些保证。除了这些保证,虚拟机可以自由地做任何他们想做的事情。因此,通常情况下,对这样一个问题的答案是:“这里是否可能刷新缓存?”是,因为你应该问更多的绝对主义问题:“这里是否保证刷新缓存?”这是一个更有趣的问题

JMM基于“发生在之前/之后”的概念。JMM定义了一些特定的场景,在这些场景中,JMM将保证代码的执行,从而使您观察到的内容与某一行发生在另一行之前的想法相匹配对于没有建立HB/HA关系的所有java代码行,JVM的行为可能会使您观察到一行在另一行之前运行,或者一行在另一行之后运行,或者甚至是一种奇怪的混合,其中部分是可观察的,而其他部分不是

换句话说,把它看作是一个邪恶的硬币:没有HB/HA,JVM为每一个交互(一个线程所做的改变)翻转硬币,这能被另一个线程观察到吗?没有Hb/HA,邪恶硬币被翻转了。这是邪恶的,因为可能性不是50/50,它只是在和你捣乱:在开发和为期一周的测试期间,它每次都成功了,就在销售人员向大客户提供演示时,它失败了

没有一种简单的方法可以测试投币是否真的发生了。然而,你的任务是确保邪恶的硬币永远不会被翻转。这是很困难的,所以在编写代码时,如果多个线程正在读写同一个字段,那么应该非常小心

volatile
access确实建立了HB/HA关系。然而,很难知道朝哪个方向发展

鉴于此代码:

// shared memory:
volatile int x = 0;
/* not volatile */ int y = 0;

// thread A:
y = 10;
x = 20;

// thread B:
if (x == 20 && y != 10) System.out.println("Augh!");
// shared state:

/* both non-volatile */ int x = 0, y = 0;

// thread A:
x = 10;
y = 20;

// thread B:
if (y == 20 && x != 10) System.out.println("AUGH!");
那你就保证了
可以从不打印。这是因为,如果将x读作20,HB/HA关系保证线程B中的行在A的第二行之后运行,因此保证观察A在第二行上或之前所做的一切。然而,你绝对不能保证这里x是20。只是,如果是,那么线程A对y所做的更改也会得到保证,即使y不是易变的

但是,在本规范中:

// shared memory:
volatile int x = 0;
/* not volatile */ int y = 0;

// thread A:
y = 10;
x = 20;

// thread B:
if (x == 20 && y != 10) System.out.println("Augh!");
// shared state:

/* both non-volatile */ int x = 0, y = 0;

// thread A:
x = 10;
y = 20;

// thread B:
if (y == 20 && x != 10) System.out.println("AUGH!");
然后JVM就完全免费了,邪恶的投币行为正在发生!JVM可以自由打印
AUGH每一次,或从未,或有时,或只有在满月时。没有HB/HA,因此VM不能保证可观察性,也不一定有意义。JVM实现允许线程B观察到对
y
的更改,而不是对
x
的更改,这是可以接受的,尽管线程实际按顺序运行代码的简化但错误的概念表明这是不可能的。基本上,如果没有HB/HA,所有的赌注都没有了

在您的代码片段中,线程A正在读取volatile变量
s
,但这是唯一可用的与
s
交互的变量;线B从不接触s

因此,此代码被破坏,邪恶的掷币行为正在发生-JVM可以按如下方式自由工作:线程2今天将
run
设置为false。尽管如此,线程1还是运行了3天,然后,似乎是在一个完全任意的时间,在您没有意识到的情况下,它突然发现
run
现在为false

或者,在线程2将
run
设置为false之后,线程1实际上立即停止

这取决于你的操作系统,CPU,winamp中播放的歌曲,月亮的相位,以及蝴蝶是否拍动翅膀。没有办法知道,也没有(简单的)方法来测试你在这里搞砸了什么。

Java内存模型(JMM)定义了一些保证。除了这些保证,虚拟机可以自由地做任何他们想做的事情。因此,通常情况下,对这样一个问题的答案是:“这里是否可能刷新缓存?”是,因为你应该问更多的绝对主义问题:“这里是否保证刷新缓存?”这是一个更有趣的问题

JMM基于“发生在之前/之后”的概念。JMM定义了一些特定的场景,在这些场景中,JMM将保证代码的执行,从而使您观察到的内容与某一行发生在另一行之前的想法相匹配对于没有建立HB/HA关系的所有java代码行,JVM的行为可能会使您观察到一行在另一行之前运行,或者一行在另一行之后运行,或者甚至是一种奇怪的混合,其中部分是可观察的,而其他部分不是

换句话说,把它看作是一个邪恶的硬币:没有HB/HA,JVM为每一个交互(一个线程所做的改变)翻转硬币,这能被另一个线程观察到吗?没有Hb/HA,邪恶硬币被翻转了。这是邪恶的,因为可能性不是50/50,它只是在和你捣乱:在开发和为期一周的测试期间,它每次都成功了,就在销售人员向大客户提供演示时,它失败了

没有一种简单的方法可以测试投币是否真的发生了。然而,你的任务是确保邪恶的硬币永远不会被翻转。这是很困难的,所以在编写代码时,如果多个线程正在读写同一个字段,那么应该非常小心

volatile
access确实建立了HB/HA关系。然而,很难知道朝哪个方向发展

鉴于此代码:

// shared memory:
volatile int x = 0;
/* not volatile */ int y = 0;

// thread A:
y = 10;
x = 20;

// thread B:
if (x == 20 && y != 10) System.out.println("Augh!");
// shared state:

/* both non-volatile */ int x = 0, y = 0;

// thread A:
x = 10;
y = 20;

// thread B:
if (y == 20 && x != 10) System.out.println("AUGH!");
那你就保证了
可以从不打印。那是因为如果