Java控制台应用设置用户输入超时的技术实现咨询
我来帮你完善这段Java控制台输入超时的实现,顺便把关键坑点给你讲清楚:
完整可运行代码
import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.concurrent.Callable; 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; public class ConsoleInputTimeout { public static void main(String[] args) { ExecutorService executor = Executors.newSingleThreadExecutor(); Callable<String> task = () -> { System.out.print("input: "); try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) { return br.readLine(); } catch (Exception e) { // 输入流被关闭时会触发该异常,直接返回null即可 return null; } }; Future<String> future = executor.submit(task); String input = null; try { // 设置10秒超时等待用户输入 input = future.get(10, TimeUnit.SECONDS); if (input != null) { System.out.println("你输入的内容是: " + input); } } catch (TimeoutException e) { System.out.println("\n输入超时!10秒内未输入任何内容"); // 仅调用cancel(true)无法中断readLine的阻塞,必须关闭输入流强制终止 future.cancel(true); try { System.in.close(); } catch (Exception ex) { ex.printStackTrace(); } } catch (Exception e) { System.out.println("输入过程中出现异常: " + e.getMessage()); e.printStackTrace(); } finally { // 关闭线程池,避免后台线程阻止JVM退出 executor.shutdown(); try { if (!executor.awaitTermination(1, TimeUnit.SECONDS)) { executor.shutdownNow(); } } catch (InterruptedException ex) { executor.shutdownNow(); } } } }
关键细节说明
为什么要关闭
System.in?
单纯调用future.cancel(true)只会给任务线程发送中断信号,但BufferedReader.readLine()是不会响应中断的——它会一直阻塞在等待输入的状态。所以必须手动关闭标准输入流,让readLine()抛出IOException,这样任务线程才能正常退出,不会一直占用系统资源。try-with-resources的作用
代码里用了try (BufferedReader br = ...)的语法,这样不管输入流程是否正常完成,流都会自动关闭,避免出现资源泄漏的问题。线程池的收尾工作
最后一定要调用executor.shutdown()并等待线程池终止,不然线程池的后台线程会阻止JVM正常退出,导致程序一直挂着无法结束。
内容的提问来源于stack exchange,提问作者Hippolyte Fayol
相关产品推荐
相关产品推荐

