Java 为什么后台线程要运行,然后在一秒钟内停止?它应该永远运行吗?

Java 为什么后台线程要运行,然后在一秒钟内停止?它应该永远运行吗?,java,multithreading,concurrency,Java,Multithreading,Concurrency,我读了第66项中名为《有效Java 2》的书,书中说后台线程将永远运行,永不停止。但是当我在电脑里运行代码时,它会在一秒钟内停止吗?发生了什么?是计算机缓存问题吗 public class StopThread { private static boolean stopRequested; public static void main(String[] args) throws InterruptedException { Thread backgroundT

我读了第66项中名为《有效Java 2》的书,书中说后台线程将永远运行,永不停止。但是当我在电脑里运行代码时,它会在一秒钟内停止吗?发生了什么?是计算机缓存问题吗

public class StopThread {
  private static boolean stopRequested;

  public static void main(String[] args)
        throws InterruptedException {
    Thread backgroundThread = new Thread(new Runnable() {
      public void run() {
        int i = 0;
        while (!stopRequested) {
          i++;
          System.out.println(i+";");
        }
      } 
    });
    backgroundThread.start(); 
    TimeUnit.SECONDS.sleep(1);
    stopRequested = true;
  }
}
书中建议使用
同步
volatile
,但我试着发现,即使我不使用该建议,它也会在我的计算机中一秒钟内运行。但是永远在我的室友身上奔跑。他说这就是缓存配置的原因


有人能告诉我原因吗?

高效Java的作者Bloch说,“在没有同步的情况下,无法保证后台线程何时(如果有的话)会看到stop Requested[SIC]值的变化。”


也就是说,它可能会立即停止。或者它可能会在短时间后停止。或者它可能永远不会停止。它不需要永远运行。因此,编译器甚至不需要删除同步。但它可以。很有可能。因此,这就是“volatile”关键字出现的地方。

高效Java的作者Bloch说的是“在没有同步的情况下,无法保证后台线程何时(如果有的话)会看到stop Requested[SIC]值的变化”


也就是说,它可能会立即停止。或者它可能会在短时间后停止。或者它可能永远不会停止。它不需要永远运行。因此,编译器甚至不需要删除同步。但它可以。很有可能。这就是“volatile”关键字的来源。

您在原始示例中添加了一行:

System.out.println(i+";");

PrintStream.println(String)
包含一个
synchronized
块,该块具有与
volatile
类似的内存一致性效果。您在原始示例中添加了一行:

System.out.println(i+";");

PrintStream.println(String)
包含一个
synchronized
块,该块具有与
volatile
类似的内存一致性效果,但是您会在一秒钟后停止线程吗<代码>同时(!stopRequested)运行直到
stopRequested=true发生在
时间单位。秒。睡眠(1)之后-等待1秒钟,然后停止线程。。。。。。。。。。。seriously@TessellatingHeckler,我不停止线程。它会自动停止。您将stopRequested的状态更改为true,当出现此状态时,while循环将写入exit,而在exit时,这将停止线程。什么使您困惑?您的代码不希望总是运行相同的代码。它可能会像对你一样停止。或者它可能根本不会停止,因为您的
stopRequested
不是易失性的,并且在一个线程中对它的更新可能不会反映在另一个线程中。嗯,但是您会在一秒钟后停止该线程吗<代码>同时(!stopRequested)
运行直到
stopRequested=true发生在
时间单位。秒。睡眠(1)之后-等待1秒钟,然后停止线程。。。。。。。。。。。seriously@TessellatingHeckler,我不停止线程。它会自动停止。您将stopRequested的状态更改为true,当出现此状态时,while循环将写入exit,而在exit时,这将停止线程。什么使您困惑?您的代码不希望总是运行相同的代码。它可能会像对你一样停止。或者它可能根本不会停止,因为您的
stopRequested
不是易变的,并且在一个线程中对它的更新可能不会反映在另一个线程中。不,不是真的。它不会同步,因为只有一个线程正在打印到标准输出。@glee8e好吧,它肯定会在后台线程上强制设置读取障碍。当主线程结束时,写操作可能会被刷新。@glee8e事实上,
println()
是使这个“工作”的更改。没有保证的行为并不保证在JMM下没有行为。但令人遗憾的是,程序永远在PO的室友的计算机上运行。同步块在读写对之间的关系之前不会发生。不,不是真的。它不会同步,因为只有一个线程正在打印到标准输出。@glee8e好吧,它肯定会在后台线程上强制设置读取障碍。当主线程结束时,写操作可能会被刷新。@glee8e事实上,
println()
是使这个“工作”的更改。没有保证的行为并不保证在JMM下没有行为。但令人遗憾的是,程序永远在PO的室友的计算机上运行。该同步块在该读写对之间建立“不发生在之前”的关系。