【问题标题】:Why does a non-daemon thread running an infinite loop stop? [closed]为什么运行无限循环的非守护线程会停止? [关闭]
【发布时间】:2016-01-15 13:18:11
【问题描述】:

我们知道,如果所有非守护线程都退出,JVM 将停止,如果非守护线程不退出,则 JVM 不会退出。但是,当我运行下面的代码时,结果似乎与我的预期不同。

public class Test{

public static void main(String[] args){

    System.out.println("start");

    new Thread(new Runnable() {
        @Override
        public void run() {
            while (true){
                System.out.println(LocalDateTime.now() + " - running");
            }
        }
    }).start();

    System.out.println("end");
    try{
        Thread.sleep(1000);
    }catch(InterruptedException e){
        System.out.println("inter");
    }
    }
}

我认为应该发生的是 JVM 不应该退出并且将永远输出running,但 1 秒后输出停止。为什么会这样?是我的理解错了还是我的测试课不合适?

更新:我尝试了命令ps | grep java,但没有结果, 当我删除sleep(1000) running 将永远打印出来,我使用的是mac和java 1.8,任何人都可以告诉我为什么会这样,谢谢!

【问题讨论】:

  • 我无法重现此行为并具有无限输出。你用的是哪个java版本?
  • 你是如何运行程序的?你确定它退出?可能是您的控制台因所有“正在运行”的打印而超载...
  • 您可以使用ps | grep java 或使用任务管理器或其他方式查看jvm 进程是否存在。所以看看它是否在那里,你不需要依赖控制台输出。还意识到“结束”可能会在您的新线程开始打印之前打印。
  • 但是你在启动它之前没有将它设置为守护线程。用户线程是您开始的默认线程,新的匿名线程正在继承它。
  • @coladict:我认为 OP 声称非守护线程不足以使 jvm 保持活动状态,这与我观察到的内容相冲突,并在此处使用控制台输出作为证据不可靠。控制台只能处理这么多的输出,并且没有任何松懈地写入标准输出是压倒它的,有人惊讶于控制台已经说得足够多的截止吗?偶尔睡一次,就像彼得劳里的例子。

标签: java multithreading jvm


【解决方案1】:

如果我跑步

import java.time.LocalDateTime;

public class Test {
    public static void main(String[] args) throws InterruptedException {
        System.out.println("start");

        new Thread(() -> {
            try {
                while (true) {
                    System.out.println(LocalDateTime.now() + " - running");
                    Thread.sleep(500);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();

        Thread.sleep(1000);
        System.out.println("end");
    }
}

我明白了

start
2016-01-15T08:30:58.378 - running
2016-01-15T08:30:58.889 - running
end
2016-01-15T08:30:59.389 - running
2016-01-15T08:30:59.890 - running
2016-01-15T08:31:00.391 - running
2016-01-15T08:31:00.892 - running
2016-01-15T08:31:01.392 - running
2016-01-15T08:31:01.893 - running
2016-01-15T08:31:02.394 - running
... many more

【讨论】:

  • 我又试了一次,sam 结果是我的问题,但是我发现当我删除 sleep(1000) 时,循环将永远运行,为什么会这样?我在 mac 和 java 1.8 上运行这段代码
  • @FireSun 除了导致线程休眠 1000 毫秒之外,睡眠应该没有任何区别。
  • 那我真的很困惑为什么会出现我的问题?
  • 我在其他平台上试过,发现这是mac问题。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-10
  • 1970-01-01
  • 1970-01-01
  • 2015-02-12
相关资源
最近更新 更多