簡體   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