使用 java.util.Scanner 的 Java 代码在使用“&”(在后台)运行时会出现“[1]+ Stopped”

问题描述 投票:0回答:1

我写了一个支持交互式命令的程序。我使用

java.util.Scanner
作为输入。

该程序也可以在后台运行,在这种情况下,不需要扫描仪。所以我想检查一下程序是否在后台运行。

事实上,当我使用

nohup java -jar my.jar &
时,扫描仪会抛出异常:

Exception in thread "main" java.util.NoSuchElementException: No line found

有了这个异常,我就可以知道这个程序正在后台运行。这不是问题。

但是,当我使用

java -jar my.jar &
时,程序就停止并显示:

[1]+  Stopped                 java -jar my.jar

没有抛出异常。就这样停了。

这是一个演示代码。您可以轻松地重现它。

import java.util.NoSuchElementException;
import java.util.Scanner;

public class ScannerTest {
    public static void main(String[] args) {
        new Thread(() -> {
            while (true) {
                System.out.println("I'm still working!");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    return;
                }
            }
        }).start();
        System.out.println("Hi~");
        try (Scanner scanner = new Scanner(System.in)) {
            String s = scanner.nextLine();
            System.out.println("s = " + s);
        } catch (NoSuchElementException e) {
            System.out.println("I'm running in the background!");
        }
        System.out.println("Bye~");
    }
}

所以我的问题是,如何在java代码中识别这种情况?如何防止它“停止”?

java linux shell input background
1个回答
0
投票

终于我自己找到了办法。当使用

java -jar my.jar &
并显示“已停止”消息时,实际上会抛出
SIGTTIN
信号。

所以我们可以为这个信号注册一个

sun.misc.SignalHandler
。就像这样:

public class MySignalHandler implements SignalHandler {
    public static void register() {
        // The returne value (i.e. the default handler) should be
        // ignored or the "Stopped" will still be shown.
        Signal.handle(new Signal("TTIN"), new MySignalHandler());
    }

    private boolean handled;

    private MySignalHandler() {
        handled = false;
    }

    @Override
    public void handle(Signal sig) {
        if (!handled) {
            // SIGTTIN may be thrown several times in a row.
            // But we only need to handle it once.
            handled = true;
            System.err.println("SIGTTIN!");
            System.exit(1);
        }
    }
}

现在程序将打印日志并退出(而不是“停止”)。

但我仍然没有找到一种方法来保持程序运行而不是让它退出。

© www.soinside.com 2019 - 2024. All rights reserved.