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

いくつかのメモ:

  • スキャナーの基になるストリームを確実にブロックしています。このコードをダウンロードして実行すると、「Trying to close the Scanner...」と表示された直後に停止します。 への呼び出しを削除するとthread.closeScanner()、「Running!」の直後に停止します。
  • interrupt()スレッドのメソッドを呼び出したいと主張するいくつかの回答を見てきました。しかし、スレッドがブロックされているため、それは機能しません。
  • Scannerが読んでいるストリームを閉じたいと主張する他の回答を見てきました。しかし、それもうまくいかないようです —Scannerドキュメントは、そのclose()メソッドが基になるストリームを閉じることを示しているので、上記のおもちゃのコードで私がやっているはずです。
  • のような非推奨のメソッドを使用することもできますstop()が、それでも効果がないようです。

何か案は?ありがとう。

(興味がある方のために説明すると、根底にある動機は、生徒の作業用に自動化されたグレーダーを作成することです。ストリームは、最終的にはスレッドによって実行されるプロセスの標準出力になります。しかし、私の生徒の中には無限ループが発生する人もいます。たとえプロセスが完了していなくても、スレッドをn秒後に終了させたい. デッドロックは実際には問題ではありません.

4

1 に答える 1

0

Scanner はこの仕事には不適切なツールだと思います。 ドキュメントには次のように書かれています

スキャン操作により、入力待ちがブロックされる場合があります。

ああ、そしてもっと重要なこと:

Scanner は、外部同期なしでマルチスレッドで使用するのは安全ではありません。

代わりに、この回答のコードを使用する必要があります: How to interrupt java.util.Scanner nextLine call

于 2014-09-09T21:46:56.343 に答える