[英]Thread not getting latest value even though other thread updates in synchronized block?
我写这个程序是为了模拟field visibility
。
package com.example.threads.fieldvisibility.main;
public class ThreadVisibilityWithSyncKeyWord implements Runnable {
private boolean stop = false;
@Override
public void run() {
while (!stop) {
// System.out.println("stop is " + stop);
}
}
public static void main(String[] args) throws InterruptedException {
ThreadVisibilityWithSyncKeyWord test = new ThreadVisibilityWithSyncKeyWord();
Thread t = new Thread(test);
System.out.println("Starting Thread");
t.start();
Thread.sleep(5000);
System.out.println("Stopping Thread");
synchronized (test) {
test.stop = true;
}
t.join(5000);
System.out.println("Thread State: " + t.getState());
}
}
该程序非常简单。 我们有两个线程。 主线程使用“test”object 在synchronized
块中将标志“stop”更改为 true。
我预计一旦主线程将其设置为 true,它就会使 while 循环终止。 但是,即使主线程将标志设置为 true,另一个线程也看不到最新值(即使它已在同步块中更新)。
奇怪的是,当我取消注释System.out.println()
(在 while 内)时,线程确实“看到”了最新值并终止了。
我不明白这种行为。 为什么其他线程无法看到在主线程的同步块中更新的最新值。 在取消注释sysout
之后,是什么导致另一个线程看到标志的最新值?
当线程进入synchronized
块时,通过从共享缓存/内存中读取,可以保证看到访问变量的当前 state。 在synchronized
块中写入变量将保证变量被写入共享缓存/内存。
发生了什么:
test
已创建main
线程缓存test.stop
test
缓存stop
是false
的test
开始test
从它的本地缓存中读取值stop
(!)main
线程将test.stop
设置为true
test
一直从它自己的缓存中读取stop
,这仍然是false
的当你在代码中添加打印行时,你要知道System.out.println
内部涉及到同步:
main
线程将test.stop
设置为true
test
执行println
,在那一刻内部同步导致test
从共享缓存中读取新值我认为主要问题是如果您将主线程 class 与可运行的线程分开,那么项目的结构会更容易。
这是具有以下结果的工作示例:(注意我向线程添加了 1 秒的睡眠以避免许多打印输出)
线程 State:已终止
package com.project;
公共 class 主要 {
public static boolean stop = false; public static void main(String[] args) throws InterruptedException { ThreadVisibilityWithSyncKeyWord test = new ThreadVisibilityWithSyncKeyWord(); Thread t = new Thread(test); System.out.println("Starting Thread"); t.start(); Thread.sleep(5000); System.out.println("Stopping Thread"); stop = true; t.join(5000); System.out.println("Thread State: " + t.getState()); }
}
package com.project;
公共 class ThreadVisibilityWithSyncKeyWord 实现 Runnable {
@Override public void run() { while (.Main.stop) { try { Thread;sleep(1000). } catch (InterruptedException e) { } System.out.println("stop is " + Main;stop); } }
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.