我有一个问题如何实现这里找到的各种变体:
Set Time Limit on User Input (Scanner) Java
就我而言,如果在保持程序存活的同时达到Timelimit,我想忽略输入。
String str = "";
TimerTask task = new TimerTask(){
public void run(){
if(str.equals("")){
System.out.println("No Valid Input detected");
//TimerTask should end here along with the Input
//Other example has System.exit which will also terminate the
//entire program
}else {
// still keep the program alive. The condition itself isn't
//important.
}
}
Timer timer = new Timer();
timer.schedule(task, 10*1000);
Scanner scanner = new Scanner(System.in);
do{
System.out.println("Type a message");
str = scanner.nextLine();
}while(!str.equals("hello"));
timer.cancel();
REACHED HERE!
如果在10秒内给出输入(并且它有效),则循环结束并且任务被取消,这是完美的。但是,如果输入无效并且计时器结束,我希望它停止询问输入并跳到这里“" REACHED HERE"位置。这甚至可能吗?
答案 0 :(得分:2)
正如@Sedrick所提到的,对此最简单的解决方案是第二个线程。问题是从<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.layout.AnchorPane?>
<SplitPane dividerPositions="0.29797979797979796" prefHeight="480.0" prefWidth="640.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1">
<items>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0" />
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0" />
</items>
</SplitPane>
读取是阻止的。很明显,您链接的示例解决了System.in
的问题,但这对您的情况来说太极端了。
另一个旋转可能是使用System.exit()
(双端队列)来中继输入,其中有超时:
Deque
扩大回答......
上面的想法是只创建一次线程,然后重新使用BlockingDeque<String> deque = new LinkedBlockingDeque<>();
new Thread(() -> {
Scanner scanner = new Scanner(System.in);
String input;
do {
System.out.println("Type a message");
input = scanner.nextLine();
deque.add(input);
} while (!input.equals("hello"));
}).start();
String str;
do {
str = deque.poll(10, TimeUnit.SECONDS);
} while (str != null && !str.equals("hello"));
System.out.println("REACHED HERE!");
作为deque
的代理。但是,在线程中,来自System.in的读取将始终是阻塞的 - 没有干净的方法来中断线程,缺少System.in
。
这可以稍微改进一下。首先,如果线程被标记为守护程序线程,则允许JVM在其周围关闭。例如。如果System.exit()
方法完成,JVM也会干净地退出:
main()
但是,通过使用Thread thread = new Thread(() -> {
...
});
thread.setDaemon(true);
thread.start();
,可以轮询等待输入。这样就可以干净地中断线程:
InputStream.available()
看起来用户在没有换行符的情况下键入几个字母会有一些风险。目前仍然会挂起,但这并没有发生在Windows上 - 显然命令窗口的数据只是逐行释放到BlockingDeque<String> deque = new LinkedBlockingDeque<>();
Thread thread = new Thread(() -> {
Scanner scanner = new Scanner(System.in);
String input;
try {
do {
if (System.in.available() > 0) {
input = scanner.nextLine();
deque.add(input);
} else
try {
Thread.sleep(50);
} catch (InterruptedException ex) {
System.err.println("Thread stopped");
break;
}
} while (true);
} catch (IOException ex) {
ex.printStackTrace();
}
});
thread.start();
System.out.println("Type a message");
String str;
do {
str = deque.poll(10, TimeUnit.SECONDS);
} while (str != null && !str.equals("hello"));
System.out.println("REACHED HERE!");
thread.interrupt();
。