为什么 volatile 关键字在 java 代码中没有按预期工作?

Why doesn't the volatile keyword work as expected in java code?

我正在Java学习并发知识。关于 volatile 关键字,它应该使变量在不同的线程中可见。但是在我的演示代码中,它似乎没有按预期工作。 class中实现Runnable的方法run()永远不会停止。

public class VisibilityDemo {

  public static void main(String[] args) throws InterruptedException {
    TimeConsumingTask timeConsumingTask = new TimeConsumingTask();
    Thread thread = new Thread(new TimeConsumingTask());
    thread.start();
    Thread.sleep(3000);
    timeConsumingTask.cancel();
  }
}

class TimeConsumingTask implements Runnable {
  private volatile boolean toCancel = false;

  @Override
  public void run() {
    while (! toCancel) {
      System.out.println("executing...");
      try {
        Thread.sleep(1000);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
    if (toCancel) {
      System.out.println("Task was canceled.");
    } else {
      System.out.println("Task done.");
    }
  }

  public void cancel() {
    toCancel = true;
    System.out.println(this + " canceled.");
  }
}

在您的主要方法中,您有两个任务实例:

  public static void main(String[] args) throws InterruptedException {
    TimeConsumingTask timeConsumingTask = new TimeConsumingTask(); //<-- one
    Thread thread = new Thread(new TimeConsumingTask()); //<-- two
    thread.start();
    Thread.sleep(3000);
    timeConsumingTask.cancel(); //<-- cancel() on first 
  }
}

您将一个传递给 Thread 构造函数,然后在另一个上调用 cancel。您需要在传递给 Thread 的实例上调用 cancel,如下所示:

  public static void main(String[] args) throws InterruptedException {
    TimeConsumingTask timeConsumingTask = new TimeConsumingTask(); 
    Thread thread = new Thread(timeConsumingTask); //<-- difference here
    thread.start();
    Thread.sleep(3000);
    timeConsumingTask.cancel();
  }
}