如何在Java测验程序中实现2秒答题限时功能?
给测验项目添加2秒答题计时器的实现方案
嘿,作为Java初学者能自己动手开发测验项目真的很棒!针对你需要给题目添加2秒答题时间限制的需求,我给你准备了两种易于理解和实现的方案,都能完美适配你的现有代码~
方案一:使用ExecutorService + Future(推荐,更简洁现代)
这个方案利用Java的并发工具类,把读取用户输入的操作放到独立线程中,主线程等待2秒后,超时就终止输入任务并判定为错误。
修改后的完整代码示例:
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; // 模拟你的Keyboard输入类(如果你的类实现不同,替换成自己的逻辑即可) class Keyboard { public static String readString() { java.util.Scanner scanner = new java.util.Scanner(System.in); return scanner.nextLine(); } } public class QuizApp { public static void main(String[] args) { int right = 0; int wrong = 0; String acr = "ASCII"; System.out.println(acr); // 创建单线程执行器处理输入读取 ExecutorService executor = Executors.newSingleThreadExecutor(); Future<String> futureAnswer = executor.submit(() -> Keyboard.readString()); try { // 最多等待2秒获取用户输入 String ans = futureAnswer.get(2, TimeUnit.SECONDS); if (ans.equalsIgnoreCase("American Standard Code For Information Exchange")) { System.out.println("Correct answer"); right++; } else { System.out.println("Wrong Answer - American Standard Code For Information Exchange"); wrong++; } } catch (TimeoutException e) { // 超时触发,判定为错误 System.out.println("Time's up! Wrong Answer - American Standard Code For Information Exchange"); wrong++; // 取消输入任务,避免线程阻塞 futureAnswer.cancel(true); } catch (Exception e) { // 处理其他输入异常 System.out.println("Error occurred while reading input: " + e.getMessage()); wrong++; } finally { // 关闭执行器释放资源 executor.shutdown(); } } }
关键部分解释:
ExecutorService:创建独立线程处理输入,避免主线程被输入操作阻塞。Future<String>:跟踪输入线程的执行结果,通过它设置等待超时时间。futureAnswer.get(2, TimeUnit.SECONDS):尝试获取输入结果,超时则抛出TimeoutException,我们在catch块中处理超时逻辑。futureAnswer.cancel(true):超时后取消输入任务,防止线程一直等待用户输入造成资源浪费。
方案二:使用Timer + TimerTask(更直观的定时任务方式)
这个方案通过设置2秒后触发的定时任务标记超时状态,主线程读取输入时同步检查超时状态。
修改后的完整代码示例:
import java.util.Timer; import java.util.TimerTask; class Keyboard { public static String readString() { java.util.Scanner scanner = new java.util.Scanner(System.in); return scanner.nextLine(); } } public class QuizApp { public static void main(String[] args) { int right = 0; int wrong = 0; boolean isTimeout = false; String acr = "ASCII"; System.out.println(acr); // 创建2秒后触发的定时任务 Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { isTimeout = true; System.out.println("\nTime's up!"); // 关闭输入流强制中断读取操作 try { System.in.close(); } catch (Exception e) { e.printStackTrace(); } } }, 2000); // 2000毫秒=2秒 try { String ans = Keyboard.readString(); // 未超时则检查答案并取消定时任务 if (!isTimeout) { timer.cancel(); if (ans.equalsIgnoreCase("American Standard Code For Information Exchange")) { System.out.println("Correct answer"); right++; } else { System.out.println("Wrong Answer - American Standard Code For Information Exchange"); wrong++; } } } catch (Exception e) { // 输入被中断(超时导致),判定为错误 if (isTimeout) { System.out.println("Wrong Answer - American Standard Code For Information Exchange"); wrong++; } else { System.out.println("Error occurred while reading input: " + e.getMessage()); wrong++; } } } }
关键部分解释:
Timer和TimerTask:创建定时任务,2秒后标记超时并关闭输入流,中断主线程的输入读取。timer.cancel():用户在超时前提交答案时,取消定时任务避免后续触发超时逻辑。- 异常处理:关闭
System.in会导致读取输入抛出异常,我们在catch块中判断是否为超时导致,再处理错误逻辑。
两种方案都能满足你的需求,方案一更推荐,因为它的并发处理更规范,不需要手动操作输入流,代码也更简洁。如果你对并发概念还不太熟悉,方案二的逻辑更直观,容易理解。
内容的提问来源于stack exchange,提问作者Luca Spiteri
相关产品推荐
相关产品推荐

