【问题标题】:One thread unable to change another thread's variable even on making the variable volatile一个线程无法更改另一个线程的变量,即使使变量变为 volatile
【发布时间】:2021-04-09 04:31:03
【问题描述】:

我有以下Processor 类:

public class Processor extends Thread {

    private volatile boolean running = true;

    @Override
    public void run() {
        while (running) {
            for (int i = 0; i < 1000; i++) {
                System.out.println("Hello " + i);
                Thread.sleep(100);
            }
        }
    }
    
    public void shutdown() {
        running = false;
    }
}

以下来自我的main 方法:

Processor processor = new Processor();
processor.start();

Scanner scanner = new Scanner(System.in);
scanner.nextLine();

processor.shutdown();

在我的Processor 类中,我有volatile boolean 变量running,我已将其设置为true。只要runningtrue,我的run 方法中的循环就会运行。我有一个单独的方法shutdown,它在执行时将running 的值设置为false,从而停止run 方法内的循环。

通过我的main 方法,我在单独的线程中运行循环,然后从主线程执行shutdown 方法。

尽管将变量running 设置为volatile,我还是无法停止循环执行。

我哪里出错了?

我正在使用 IntelliJ IDE。

【问题讨论】:

  • 尝试从控制台中删除读取任何内容(例如,将其替换为一些sleep
  • for循环中添加这个:if (!running) break;
  • 使用线程中断来阻止线程进一步执行,将中断检查放在 while(true) 之后,如果被中断则中断,如果你仍然使用基于变量的检查,也使用原子引用,但是如果仍然想使用 volatile 然后在关闭方法上放置一个 synchronized 关键字,以确保硬写入 ram。
  • 外部检查 (while (running)) 仅在内部 for 完成工作后检查 - 所以每 ~ 100 秒一次。
  • for (int i = 0; i &lt; 1000; i++) 替换为for (int i = 0; i &lt; 1000 &amp;&amp; running; i++) 并删除while (running)

标签: java multithreading loops caching volatile


【解决方案1】:

您需要交换 while 和 for 循环。这样就可以把运行短路了

        for (int i = 0; i < 1000; i++) {
    while (running) {
            System.out.println("Hello " + i);
            Thread.sleep(100);
        }
    }

我已经让你修复缩进了:)

【讨论】:

  • 好的,但我的主要目标是使用volatile keyword。为什么它不起作用?
  • 这里,这个程序无足轻重,我正在学习 volatile 关键字的使用,我的主要查询是 - 即使使用了 volatile,第二个线程也不让主线程更改变量值?
  • “为什么它不起作用?” - 这是您的代码中的一个简单的逻辑问题。您编写的代码仅每 100 秒测试一次标志。
  • @PayelSenapati 实际上,问题 很重要,因为在您编写的原始代码中,一旦第一个 running 检查被清除,它 *永远不要再检查它,也没有办法让它短路/停止它
最近更新 更多