gpt4 book ai didi

Java:使用Executorservice和future作为计时器时如何打破循环?

转载 作者:行者123 更新时间:2023-12-01 17:41:44 25 4
gpt4 key购买 nike

我正在尝试为一个简单的数学测验制作一个计时器,用户需要在 10 秒内回答问题,当时间超过时,它将加载到下一个问题。我找到了实现 Executorservice 和 future 的解决方案,但是当用户输入整数以外的其他输入时,它不断重复无效输入循环(数字格式异常),我遇到了问题> 在我的游戏课上。

希望了解以下内容有用: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;
}
}

这是输出循环问题的图片:loop problem

我已经尝试寻找计时器的解决方案很长一段时间了,如果有人可以提供帮助,我将非常感激。非常感谢。

*附加:有没有办法显示计时器倒计时(例如: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 键继续。

关于Java:使用Executorservice和future作为计时器时如何打破循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60942194/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com