简体   繁体   English

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

[英]Stopping a Java thread blocked on a Scanner

This is related to some other questions on here, but I haven't yet seen an answer that helps. 这与这里的其他一些问题有关,但是我还没有看到一个有帮助的答案。 ( EDIT by JWW: per the comments, the cited duplicate doe not handle the EOF as expected or desired). (由JWW 编辑 :根据评论,引用的重复的doe不能按预期或期望的方式处理EOF )。

In this example, the main() function starts a Thread, which blocks on a Scanner's nextLine() function. 在此示例中, main()函数启动一个线程,该线程在扫描程序的nextLine()函数上nextLine() I then wait for 0.2 s, and after that time I want to force this Thread to terminate, even though nothing's been typed in. I can't get the Thread to stop on its own, without hitting a key to satisfy its Scanner. 然后,我等待0.2 s,在那之后,我想强制终止该Thread,即使没有输入任何内容。我也无法让Thread自行停止,而无需按下键来满足其Scanner。

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.");
        }
    }
}

Some notes: 一些注意事项:

  • It's definitely blocking on the Scanner's underlying stream. 它肯定会阻塞扫描程序的基础流。 If you download and run this code, it'll halt right after printing "Trying to close the Scanner..." If you remove the call to thread.closeScanner() , it'll stop immediately after "Running!" 如果下载并运行此代码,它将在打印“正在尝试关闭扫描仪...”之后立即停止。如果删除对thread.closeScanner()的调用,它将在“运行!”之后立即停止。
  • I've seen some answers claiming that I want to call the Thread's interrupt() method. 我已经看到一些答案,声称要调用Thread的interrupt()方法。 But that doesn't work, because the Thread is blocked. 但这是行不通的,因为线程被阻塞了。
  • I've seen other answers claiming that I want to close the stream that the Scanner is reading. 我已经看到其他答案,声称我想关闭Scanner正在读取的流。 But that doesn't seem to work either— Scanner docs indicate that its close() method closes the underlying stream, so that should be what I'm doing in the above toy code. 但这似乎也不起作用— Scanner文档表明其close()方法关闭了基础流,因此这应该是我在上面的玩具代码中所做的。
  • I'd even be willing to use a deprecated method like stop() , but even that appears to have no effect. 我什至愿意使用不推荐使用的方法,如stop() ,但即使这样似乎也没有效果。

Any ideas? 有任何想法吗? Thanks. 谢谢。

(If you're curious, the underlying motivation is to create an automated grader for my students' work. The stream will ultimately be the stdout of a process being executed by a thread. But some of my students will have infinite loops, and I want the thread to terminate after n seconds, even if the process hasn't completed. So deadlock isn't really a concern, since I'm really not doing much in the way of synchronization.) (如果您好奇的话,其潜在动机是为我的学生的工作创建一个自动评分器。流最终将成为线程正在执行的流程的标准输出。但是我的某些学生会有无限循环,而我希望线程在n秒后终止,即使进程尚未完成。因此,死锁也不是一个真正的问题,因为我在同步方面做得并不多。)

I think that Scanner is the wrong tool for the job. 我认为Scanner是这项工作的错误工具。 The documentation says : 该文件说

A scanning operation may block waiting for input. 扫描操作可能会阻止等待输入。

Oh, and more importantly: 哦,更重要的是:

A Scanner is not safe for multithreaded use without external synchronization. 没有外部同步的情况下,扫描程序不能安全用于多线程。

You should use the code in this answer instead: How to interrupt java.util.Scanner nextLine call 您应该改用此答案中的代码: 如何中断java.util.Scanner nextLine调用

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM