java - 停止扫描仪上阻塞的 Java 线程

标签 java multithreading stream blocked

这与这里的其他一些问题有关,但我还没有看到有帮助的答案。 (JWW编辑:根据注释,引用的重复项未按预期或期望处理EOF)。

在此示例中,main() 函数启动一个线程,该线程会阻塞 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.");
        }
    }
}

一些注意事项:

  • 它肯定会阻塞扫描仪的底层流。如果您下载并运行此代码,它将在打印“尝试关闭扫描仪...”后立即停止。如果您删除对 thread.closeScanner() 的调用,它将在打印后立即停止“跑!”
  • 我看到一些答案声称我想调用线程的 interrupt() 方法。但这不起作用,因为线程被阻塞。
  • 我看到其他答案声称我想关闭 Scanner 正在读取的流。但这似乎也不起作用 - Scanner 文档表明其 close() 方法关闭底层流,因此应该我正在上面的玩具代码中做。
  • 我什至愿意使用像 stop() 这样已弃用的方法,但即使这样似乎也没有效果。

有什么想法吗?谢谢。

(如果您好奇的话,潜在的动机是为我的学生的作业创建一个自动评分器。流最终将成为由线程执行的进程的标准输出。但是我的一些学生将有无限循环,并且我希望线程在 n 秒后终止,即使该过程尚未完成。因此死锁并不是真正的问题,因为我实际上没有在同步方面做太多事情.)

最佳答案

我认为扫描仪不适合这项工作。 The documentation says :

A scanning operation may block waiting for input.

哦,更重要的是:

A Scanner is not safe for multithreaded use without external synchronization.

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

关于java - 停止扫描仪上阻塞的 Java 线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25753876/

相关文章:

c++ - Linux - 限制每个进程的线程数

java - 我如何创建一个新文件并放入一些用户定义的整数(使用 Scanner 类)然后读取它?

java - cxf Web 服务不更新

java - 指定 Cipher.getInstance() 参数?

java - 从 UI 线程调用 GattCallback 中的函数

objective-c - Objective-C 之外有什么类似于 Grand Central Dispatch 的东西吗?

amazon-web-services - 有没有办法清除 dynamoDB 流?

C#:从文本文件中读取枚举

c# - HttpWebRequest 分块/异步 POST

java - 无法实现不安全线程