I have two threads running, userInputThread
waits for user input from the command line and interrupterThread
tries to interrupt userInputThread
1 sec after starting. Obviously you cannot interrupt a thread that is blocked by the System.in
. Another answer suggests to close System.in
with System.in.close()
before interrupting a thread. But when I run the following code, the userInputThread
never gets interrupted and the app just hangs without closing.
class InputInterruptionExample {
private Thread userInputThread;
private Thread interrupterThread;
InputInterruptionExample() {
this.userInputThread = new Thread(new UserInputThread());
this.interrupterThread = new Thread(new InterrupterThread());
}
void startThreads() {
this.userInputThread.start();
this.interrupterThread.start();
}
private class UserInputThread implements Runnable {
public void run() {
try {
System.out.println("enter your name: ");
String userInput = (new BufferedReader(new InputStreamReader(System.in))).readLine();
} catch (IOException e) {
System.out.println("Oops..somethign went wrong.");
System.exit(1);
}
}
}
private class InterrupterThread implements Runnable {
public void run() {
try {
sleep(1000);
System.out.println("about to interrupt UserInputThread");
System.in.close();
userInputThread.interrupt();
userInputThread.join();
System.out.println("Successfully interrupted");
} catch (InterruptedException e) {
} catch (IOException ex) {
System.out.println("Oops..somethign went wrong.");
System.exit(1);
}
}
}
public static void main(String[] args) {
InputInterruptionExample exampleApp = new InputInterruptionExample();
exampleApp.startThreads();
}
}
There's already a similar question, but there aren't any definite answers.
All of my research leads me to believe that the underlying .read() in the .readLine() call cannot be interrupted (Without destroying the Process that System.in is attached to, at least). The only other choices at that point is to use a polling IO scheme or switch to NIO.
Here's a quick (and very dirty/ugly) adaptation of your code into a polling IO scheme. It's not an interupt solution so it's not directly answering your question, but rather hopefully getting you the behavior you desire.
This has solved the problem:
Update: This only works when BufferedReader is split up this way:
For some reason the interruption does not seem to work when the readLine() structure is written as a oneliner:
So while it is possible to interrupt the thread in the split-up BufferedReader structure, it is now impossible to read user's input.
If someone could show a way to be able to get user input as well as interrupt the UserInputThread when the user doesn't provide any input in time (while interrupter is sleeping), please do.