How to interrupt java.util.Scanner nextLine call

j-pb picture j-pb · Feb 13, 2011 · Viewed 10.9k times · Source

I am using a multi threaded environment were one Thread is constantly listening for user input by repeatedly calling scanner.nextLine(). To end the application, this runloop is stopped by another thread, but the listening thread won't stop until a last user input was made (due to the blocking nature of nextLine()).

Closing the stream seems not to be an option since I am reading from System.in, which returns an InputStream that is not closable.

Is there a way to interrupt the blocking of scanner, so that it will return?

thanks

Answer

djna picture djna · Feb 13, 2011

This article describes an approach to avoiding blocking when reading. It gives the code snippet, which you could amend as I indicate in a comment.

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;
  }
}

You could either use this code directly, or write a new closable InputStream class, wrapping up the logic described in this article.