停止在扫描程序上阻止的Java线程

时间:2014-09-09 21:33:01

标签: java multithreading stream blocked

这与其他一些问题有关,但我还没有看到一个有帮助的答案。 (编辑:JWW:根据评论,引用的副本不按预期或期望处理EOF。)

在此示例中,main()函数启动一个Thread,它会阻止Scanner的nextLine()函数。然后我等待0.2秒,在那段时间之后我想强制终止此线程,即使没有输入任何内容。我不能让线程自行停止,而不需要按键满足其扫描仪。

import java.util.*;

class sandbox {
    public static void main(String[] args) {
        BlockingThread thread = new BlockingThread();
        thread.start();

        trySleep(200); // wait 0.2 s
        thread.closeScanner(); // try to close the Scanner, to terminate the Thread
    }

    public static void trySleep(int time) {
        try { Thread.sleep(time); }
        catch (InterruptedException e) {}
    }

    static class BlockingThread extends Thread {
        private Scanner scanner = new Scanner(System.in);

        public void run() {
            System.out.println("Running!");
            scanner.nextLine();
            System.out.println("Stopping!");
        }

        public void closeScanner() {
            System.out.println("\tTrying to close the Scanner...");
            scanner.close();
            System.out.println("\tScanner is now closed.");
        }
    }
}

一些注意事项:

  • 它肯定会阻止Scanner的底层流。如果您下载并运行此代码,它将在打印后立即停止"尝试关闭扫描仪..."如果您取消对thread.closeScanner()的通话,则会在"正在运行后立即停止!"
  • 我已经看到一些答案声称我想调用Thread的interrupt()方法。但这不起作用,因为线程被阻止了。
  • 我已经看到其他答案声称我要关闭Scanner正在阅读的信息流。但这似乎也无效 - Scanner文档表明其close()方法会关闭基础流,因此成为我正在做的事情在上面的玩具代码中。
  • 我甚至愿意使用像stop()这样的弃用方法,但即使这样也没有效果。

有什么想法吗?感谢。

(如果你很好奇,其根本动机是为我的学生创建一个自动分级器。这个流最终将成为一个线程正在执行的进程的标准。但是我的一些学生将有无限循环,并且我希望线程在 n 秒后终止,即使进程尚未完成。所以死锁并不是真正的问题,因为我'我真的没有采取同步的方式。)

1 个答案:

答案 0 :(得分:0)

我认为Scanner是错误的工具。 The documentation says

  

扫描操作可能会阻止等待输入。

哦,更重要的是:

  

如果没有外部同步,扫描程序对于多线程使用是不安全的。

您应该使用此答案中的代码:How to interrupt java.util.Scanner nextLine call