![](/img/trans.png)
[英]How does ExecutorService in Java behave if future is inside a loop
[英]Java: How to break loop when using Executorservice and future for timer?
我正在尝试为一个简单的数学测验制作一个计时器,用户需要在 10 秒内回答问题,当超过该时间时,它将加载到下一个问题。 我找到了实现 Executorservice 和 future 的解决方案,但是当用户在我的 Game 类中输入除整数以外的其他输入时,它不断重复循环以获取无效输入(数字格式异常)时遇到问题。
希望这对了解有用:类 MathQuestion(生成数学问题的地方)、Game(开始的游戏回合)和 GameTimer。
游戏类:-
//for 10 rounds of game
for (int i=0; i<rounds; ++i)
{
System.out.println("*************************************");
System.out.println("\nRound " + (i+1)
+ "\nEnter 'x' to quit game");
System.out.println("\nQuestion:");
//call method to generate question and get correct answer
result = quiz.Questions();
System.out.println("You have 10 seconds");
//to make sure we read a line or interrupt it for the timer
ExecutorService ex = Executors.newSingleThreadExecutor();
try
{
//retrieve the actual result at a later point in time.
Future<String> ans = ex.submit(new GameTimer());
try {
boolean validInput = false;
do
{
System.out.println("\nEnter your answer: ");//prompt user input answer
//10 secs wait to obtain result from player
//wait until callable complete before return result
answer = ans.get(10, TimeUnit.SECONDS);
//answer = scan.nextLine();
try
{
//valid player input
pAnswer = Double.parseDouble(answer.trim()) ; //convert to double
validInput = true;
}catch (NumberFormatException e){ //other input other than integers *this the repeated loop
System.out.println("Invalid input. Please try again.");
validInput = false;
ans = ex.submit(new GameTimer()); //resubmit task solution
}
if (answer.trim().equalsIgnoreCase("x")) //player quit game
{
quit=true;
break;
}
}while (!validInput);
if (quit)
{
break;
}
//for correct answer
if (Math.abs(Double.parseDouble(answer) - quiz.answer) <= 0.01) {
//add 10 points
this.gamer.setScore(score+=10);
System.out.println("You got it right!");
}
else //wrong answwer
{
//subtract 10 points
this.gamer.setScore(score-=10);;
System.out.println("You got it wrong!");
}
} catch (InterruptedException ex1) {
Logger.getLogger(Game.class.getName()).log(Level.SEVERE, null, ex1);
} catch (ExecutionException ex1) {
Logger.getLogger(Game.class.getName()).log(Level.SEVERE, null, ex1);
} catch (TimeoutException ex1) {
System.out.println ("\nTime's up! Better luck next time~");
}
}finally {
ex.shutdownNow(); //stop all running tasks and shut the executor down immediately.
}
}
GameTimer 类:-
public class GameTimer implements Callable<String> {
public String call() throws IOException {
BufferedReader inp = new BufferedReader(new InputStreamReader(System.in));
String input = "";
while ("".equals(input)) {
try {
while (!inp.ready()) {
Thread.sleep(1000);
}
input = inp.readLine();
} catch (InterruptedException e) {
return null;
}
}
return input;
}
}
这是输出循环问题的图片:循环问题
很长一段时间以来,我一直在努力为计时器寻找解决方案,如果有人能提供帮助,我将不胜感激。 非常感谢。
*附加:有没有办法显示该计时器倒计时(例如:10 9 8 ..)但在新的秒数出现时擦除前一秒?
(不擦除建议也有帮助,谢谢!)
你不能一直重新调用 get。 您的任务是一个可执行文件,您提交它并运行。 您调用 .get 并获取执行结果。 您需要重新提交任务,例如:
catch (NumberFormatException e){ //other input other than integers *this the repeated loop
System.out.println("Invalid input. Please try again.");
validInput = false;
ans = ex.submit(new GameTimer());
}
您可能希望跟踪自从每次调用 get 时都使用相同的超时时间以来经过的时间。
在我看来,你应该把错误处理放在你的可调用文件中。
final String question = "Enter double value";
Callable<Double> getDouble = ()-{
BufferedReader inp = new BufferedReader(neww InputStreamReader(System.in));
while (!Thread.currentThread().isInterupted()) {
System.out.println(question);
try {
String input = inp.readLine();
Double v = Double.parseDouble(v);
return v;
} catch(Exception e){
if( Thread.currentThread().isInterrupted()){
return null;
}
System.out.println("Invalid Input, try again");
}
}
}
现在,当您提交任务时,您不必担心无效的 double,因为它是在可调用任务中处理的。
Future<Double> ans = ex.submit(getDouble);
Double v = ans.get(10, TimeUnit.SECONDS);
这会留下一个问题:任务即使被取消仍会等待标准输入。 解决此问题的最简单方法是告诉您的用户按 Enter 继续。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.