1

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

在这个例子中,main()函数启动了一个线程,它阻塞了一个扫描器的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秒后终止,即使进程尚未完成。所以死锁并不是真正的问题,因为我在同步方面真的没有做太多事情。)

4

1 回答 1

0

我认为扫描仪是不适合这项工作的工具。 文档说

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

哦,更重要的是:

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

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

于 2014-09-09T21:46:56.343 回答