Как прервать вызов java.util.Scanner nextLine - PullRequest
7 голосов
/ 13 февраля 2011

Я использую многопоточную среду, в которой один поток постоянно прослушивает ввод пользователя, неоднократно вызывая scanner.nextLine().Чтобы завершить приложение, этот цикл выполнения останавливается другим потоком, но поток прослушивания не будет остановлен, пока не будет сделан последний пользовательский ввод (из-за природы блокировки nextLine()).

Кажется, закрытие потокане вариант, так как я читаю из System.in, который возвращает InputStream, который не подлежит закрытию.

Есть ли способ прервать блокировку сканера, чтобы он вернулся?

спасибо

Ответы [ 2 ]

8 голосов
/ 13 февраля 2011

Эта статья описывает подход к предотвращению блокировки при чтении. Он дает фрагмент кода, который вы можете изменить, как я указал в комментарии.

import java.io.*;
import java.util.concurrent.Callable;

public class ConsoleInputReadTask implements Callable<String> {
  public String call() throws IOException {
    BufferedReader br = new BufferedReader(
        new InputStreamReader(System.in));
    System.out.println("ConsoleInputReadTask run() called.");
    String input;
    do {
      System.out.println("Please type something: ");
      try {
        // wait until we have data to complete a readLine()
        while (!br.ready()  /*  ADD SHUTDOWN CHECK HERE */) {
          Thread.sleep(200);
        }
        input = br.readLine();
      } catch (InterruptedException e) {
        System.out.println("ConsoleInputReadTask() cancelled");
        return null;
      }
    } while ("".equals(input));
    System.out.println("Thank You for providing input!");
    return input;
  }
}

Вы можете использовать этот код напрямую или написать новый закрываемый класс InputStream, обернув логику, описанную в этой статье.

0 голосов
/ 05 июля 2017

Конечно.Используйте ядерное оружие.Звоните System.exit(0) в конце вашего основного потока.Это убьет все.Даже активный поток, ожидающий в System.in.

Проблема заключается в том, что System.in является традиционным входным потоком с блокировкой, а когда он блокируется, поток помечается как работающий.Вы не можете прервать это.Поэтому любой поток, который вы используете для чтения System.in, вызывает read, и чтение блокирует поток.Некоторые из этих вещей можно обмануть кучей трюков, избегая вызова read, за исключением тех случаев, когда мы можем быть уверены, что блока не будет, а затем постоянно опрашивать.Но в действительности нет способа обойти проблему, что любая попытка чтения, которая заблокирует ваш поток, и никакое количество закрытия базовых потоков или прерывания или остановки потока не спасет вас.Но, если вы убьете весь vm ... поток умрет.

Очевидно, вам нужно убедиться, что остальные потоки правильно завершены, и это всего лишь одна глупость, на которую я хочу ответитьТипизированный поток ввода, который является последним вешалкой.Но, если это полностью так, правильный ответ - это выйти, или, по крайней мере, по сути, единственный ответ, который будет работать без записи тактов без причины и позволить программе завершиться.

...