繁体   English   中英

Java:如何在使用 Executorservice 和 future for timer 时中断循环?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM