java - Java中超时的用户输入
问题描述
我正在尝试使用此功能构建命令行界面:如果用户花费超过 15 秒来插入输入(在本例中为整数),则该函数会做出默认选择 (0)。下面的代码是我到目前为止写的,它工作正常。
问题是我想添加一个新功能:如果用户输入错误的数字(<0 或 >range),控制台应该打印类似("Wrong choice, you have to pick an integer between 0 - "+ range);
但是,当控制台打印消息时,计时器应该仍在运行并在 15 秒后结束此循环,以防用户不断插入错误的数字。如果用户最终得到一个正确的数字,它应该立即中断循环。
这是我的代码,但我对如何添加功能没有明确的想法,因为我对 Future、Callable 和 Executor 功能相对较新。如果有人对此有更多经验,我将很高兴学习!
private int getChoiceWithTimeout(int range){
Callable<Integer> k = () -> new Scanner(System.in).nextInt();
Long start= System.currentTimeMillis();
int choice=0;
ExecutorService l = Executors.newFixedThreadPool(1); ;
Future<Integer> g;
System.out.println("Enter your choice in 15 seconds :");
g= l.submit(k);
while(System.currentTimeMillis()-start<15*1000 && !g.isDone()){
// Wait for future
}
if(g.isDone()){
try {
choice=g.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
g.cancel(true);
return choice;
}
解决方案
您可以使用标记的 break(done:
在下面给出的代码中)和boolean
变量(valid
在下面给出的代码中)来跟踪输入是否有效。
import java.util.Scanner;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Main {
public static void main(String[] args) {
// Test
System.out.println(getChoiceWithTimeout(10));
}
static int getChoiceWithTimeout(int range) {
Callable<Integer> k = () -> new Scanner(System.in).nextInt();
Long start = System.currentTimeMillis();
int choice = 0;
boolean valid;
ExecutorService l = Executors.newFixedThreadPool(1);
Future<Integer> g;
System.out.println("Enter your choice in 15 seconds :");
g = l.submit(k);
done: while (System.currentTimeMillis() - start < 15 * 1000) {
do {
valid = true;
if (g.isDone()) {
try {
choice = g.get();
if (choice >= 0 && choice <= range) {
break done;
} else {
throw new IllegalArgumentException();
}
} catch (InterruptedException | ExecutionException | IllegalArgumentException e) {
System.out.println("Wrong choice, you have to pick an integer between 0 - " + range);
g = l.submit(k);
valid = false;
}
}
} while (!valid);
}
g.cancel(true);
return choice;
}
}
示例运行:不要输入任何内容,该方法将0
在 15 秒后返回,就像它当前对您的代码所做的那样
Enter your choice in 15 seconds :
0
另一个示例运行:用户输入一个有效数字后,该方法将返回输入的值;否则,它将0
在 15 秒后继续询问有效输入或返回。
Enter your choice in 15 seconds :
a
Wrong choice, you have to pick an integer between 0 - 10
12
Wrong choice, you have to pick an integer between 0 - 10
5
5
注意:使用标签break
不是强制性的,您可以将其替换为传统的break
ing 方式,但这需要您添加更多代码行。
推荐阅读
- python - 如何创建仅包含修改数据的新 csv 文件?(熊猫)
- c3.js - c3.js条形图:如何对角显示数据标签
- powerbi - 在 D365 中为 Finance and Operations 自定义 Power BI 报表
- javascript - Javascript + Spring Boot + Thymeleaf - 表单验证
- python - 如何将列表中的多个项目与另一个列表中的一个元素匹配?
- c# - API 调用后无法反序列化当前 JSON 数组
- javascript - window.settimeout 功能在 ios safari 和 android 浏览器中无法正常工作
- google-apps-script - GOOGLE FORM - 如何指定我要在 Google 表单中上传文件的文件夹名称?
- javascript - 是否有任何选项可以从对象数组中单独获取键值并将其作为单引号内的单独对象数组
- javascript - 使用 JSON.parse 和 JSON.stringify 的 Javascript 深拷贝