最简单的解决方案是在“读取”线程中公开基础流,并从超时线程中关闭该流.这会打断阅读并引发异常.处理此异常,您应该可以继续执行逻辑.唯一的问题是您将无法再次使用相同的流.不幸的是,没有简单的方法来处理阻塞系统调用的中断.
编辑:
遵循完全不同的推理路线;鉴于我们不能仅仅为了中断输入流而关闭输入流,所以我想到的唯一方法是使用Robot类提供的“程序用户输入”功能.这是一个适合我的示例:
import java.awt.Robot;
import java.awt.event.KeyEvent;
import java.util.Scanner;
import java.util.concurrent.TimeUnit;
public class ConsoleTest {
/**
* @param args
*/
public static void main(String[] args) {
new TimeoutThread().start();
new ReaderThread().start();
}
}
class ReaderThread extends Thread {
@Override
public void run() {
System.out.print("Please enter your name: ");
try(Scanner in = new Scanner(System.in)) {
String name = in.nextLine();
if(name.trim().isEmpty()) {
name = "TEST"; // default user name
}
System.out.println("Name entered = " + name);
}
}
}
class TimeoutThread extends Thread {
@Override
public void run() {
try {
Thread.sleep(TimeUnit.SECONDS.toMillis(5));
Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_ENTER);
robot.keyRelease(KeyEvent.VK_ENTER);
} catch(Exception e) {
e.printStackTrace();
}
}
}
上面的代码使用的逻辑是,一旦超时到期,我们将模拟换行符,这将导致“ name”变量为空.然后我们进行检查,该检查执行必要的逻辑并设置适当的用户名.
关于上述方法的陷阱是:
>使用AWT的机器人类,因此可能无法在无头终端上正常播放(?)
>假设焦点窗口是控制台窗口.如果焦点在其他位置,则将在该窗口而不是您的应用程序窗口注册ENTER键.
希望这可以帮助你.我现在真的没主意了. ?