java - java 8中是否存在并发时发生的liveness failure

标签 java multithreading concurrency java-8

我将尝试重现 Effective Java(第二版)中提到的以下代码。 属于 Chapter 10 Concurrency Item 66.

public class StopThread {
   private static boolean stopRequested;

   public static void main(String args[]) {
      Thread backgroudThread = new Thread(new Runnable(){
             public void run() {
                int i = 0;
                while(!stopRequested) {
                       i ++;
                }
             }
      });
      backgroudThread.start();

      TimeUnit.SECONDS.sleep(1);
      stopRequested = true;
   }
}

根据作者的描述,当您运行上述程序段时,backgroupdThread 不会终止。但是我无法在设置 Java8 环境的机器上重现它。那么这个问题在Java最新版本中有优化吗?

已更新
我在 linux 操作系统 (redhat) 中再次尝试。它总是不会终止。在我在 Win7 操作系统 COREi5 中运行它之前。它总是终止。

PS: 在linux 操作系统(redhat) 中。如果按照上面的代码运行,程序将不会终止。但是,如果我在“while”循环中的“i++”之后添加“System.out.println(i)”。此时。程序将始终终止。这是我的新发现。如果您知道原因,请发布您的答案。我将继续钻研这些系列问题,直到找到真正的原因。

最佳答案

好吧,如果更准确的话,作者写道:

On my machine, however, the program never terminates: the background thread loops forever!

现在你仍然可以反驳那个原因,因为他显然没有“永远”运行这个程序,但你明白了。

顺便说一句,在我的机器上,程序永远不会终止(JDK 1.7.0_45)
顺便说一句 2:如果我们希望它终止,我们所要做的就是将 stopRequested 声明为 volatile

更新:
为了为那些没有这本书的人提供更多背景信息(您真的应该得到它!),作者稍后解释了这可能发生的原因是由于编译器检测到 stopRequested 未在本地更改,因此允许进行以下优化:

while(!stopRequested) {
      i ++;
}

变成:

if (!stopRequested)
    while(true) {
          i ++;
    }

JVM 热点进行这种优化(称为提升)。如果您想更深入地了解为什么这是一个合法的优化,您应该阅读一下:JLS §17.4.3 Programs and Program Order

关于java - java 8中是否存在并发时发生的liveness failure,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24730412/

相关文章:

java - 是否有原因导致线程仅在我强制调试时才执行?

java - 调用values()时需要同步并发HashMap吗?

java - 如何在 Infinispan 中使用 JTA 事务?

java - GridBag 面板不占用所有空间

java - 用于即时读取/拉取的自定义缓冲输入流

C++:在按 ENTER 之前读取字符

multithreading - 功能语言中的并行性

c# - .NET 中的多线程绘图?

java - 了解何时以及如何使用 Java 8 Lambdas

用于服务帐户的基于 Java 的 Google App Engine 和 Google Drive API