为什么我的布尔变量在停止线程循环时应该是易变的?
Why my boolean variable should be volatile while stopping thread loop?
假设我有一个包含 while 循环的线程,我想停止它 "from outside"。
public class MyThread extends Thread {
private boolean running = true;
@Override
public void run() {
while (running) {
// do something
}
}
public void setRunning(boolean running) {
this.running = running;
}
}
这是主要内容 class:
public class Main {
public static void main(String[] args) {
MyThread mt = new MyThread();
mt.start();
// do something
mt.setRunning(false);
}
}
它似乎停止正常,但我读到布尔值也应该是易变的。为什么?会不会加速停止?
使用 Volatile 状态将立即在主内存中更新。因此,一旦 running
更新,并发线程将立即看到更新后的状态。
更新 :- 它在你的情况下工作正常可能是因为你没有足够数量的多线程或者如果你有那么到那个时候状态已经在 main 中更新那时的记忆。观察这种行为以设置负载测试的最佳方式(使用 Jmeter 等工具)。这表明为什么牢牢把握 theoretical/basic 概念很重要,否则您会在生产环境中遇到此类问题,因为某些项目没有 budget/timelines 来进行负载测试
当并发线程将缓存 运行 变量时,这意味着它将缓存在线程工作内存中。
Java 中的 volatile 关键字用作 Java 编译器和线程的指示器,它们不会缓存此变量的值并始终从主内存中读取它。所以如果你想共享任何变量,其中读写操作是原子的,你必须声明为 volatile 变量。
看看下面的图片你会有好主意
假设我有一个包含 while 循环的线程,我想停止它 "from outside"。
public class MyThread extends Thread {
private boolean running = true;
@Override
public void run() {
while (running) {
// do something
}
}
public void setRunning(boolean running) {
this.running = running;
}
}
这是主要内容 class:
public class Main {
public static void main(String[] args) {
MyThread mt = new MyThread();
mt.start();
// do something
mt.setRunning(false);
}
}
它似乎停止正常,但我读到布尔值也应该是易变的。为什么?会不会加速停止?
使用 Volatile 状态将立即在主内存中更新。因此,一旦 running
更新,并发线程将立即看到更新后的状态。
更新 :- 它在你的情况下工作正常可能是因为你没有足够数量的多线程或者如果你有那么到那个时候状态已经在 main 中更新那时的记忆。观察这种行为以设置负载测试的最佳方式(使用 Jmeter 等工具)。这表明为什么牢牢把握 theoretical/basic 概念很重要,否则您会在生产环境中遇到此类问题,因为某些项目没有 budget/timelines 来进行负载测试
当并发线程将缓存 运行 变量时,这意味着它将缓存在线程工作内存中。
Java 中的 volatile 关键字用作 Java 编译器和线程的指示器,它们不会缓存此变量的值并始终从主内存中读取它。所以如果你想共享任何变量,其中读写操作是原子的,你必须声明为 volatile 变量。
看看下面的图片你会有好主意