![](/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.