You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何终止已启动的TimerTask?TimerTask致循环中断问题求助

解决TimerTask超时导致循环中断的问题

核心问题分析

你的代码存在两个关键问题:

  • 用户在5秒内输入指令后,未取消已调度的TimerTask,导致它仍会在5秒后执行,干扰后续循环流程。
  • 没有处理超时未输入的情况,主线程会一直阻塞在sc.nextLine(),导致循环无法继续推进。

解决方案

我们需要:

  • 在用户输入后立即取消TimerTask和Timer,避免后续干扰。
  • 结合计时判断处理用户未按时输入的场景,让循环能正常继续。

修改后的代码如下:

import java.util.Scanner;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Random;

public class Main {
    public static void main(String[] args) throws Exception {
        int hp = 10;
        Scanner sc = new Scanner(System.in);
        Timer czas = null;
        TimerTask zd = null;
        boolean isTimeout = false;

        do {
            isTimeout = false;
            Random los = new Random();
            int pc = 1 + los.nextInt(6);

            zd = new TimerTask() {
                public void run() {
                    System.out.println("Czas off");
                    System.out.println("5 sek");
                    isTimeout = true;
                    // 超时后解除Scanner的阻塞
                    try {
                        System.in.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            };

            czas = new Timer();
            czas.schedule(zd, 5 * 1000);
            System.out.println("5 sek na odp");

            // 等待输入或超时
            long startTime = System.currentTimeMillis();
            String odp = null;
            while (System.currentTimeMillis() - startTime < 5000 && !sc.hasNextLine()) {
                Thread.sleep(100);
            }

            // 强制取消定时任务,避免后续干扰
            if (zd != null) zd.cancel();
            if (czas != null) {
                czas.cancel();
                czas.purge();
            }

            if (isTimeout) {
                System.out.println("超时未输入!");
                hp = hp - pc;
                System.out.println("hp spadlo o " + pc + " wynosi " + hp);
                // 重置Scanner,避免后续输入异常
                sc = new Scanner(System.in);
            } else {
                odp = sc.nextLine();
                switch (odp) {
                    case "atk":
                        System.out.println("oo tak");
                        hp = hp - pc;
                        System.out.println("hp spadlo o " + pc + " wynosi " + hp);
                        break;
                    default:
                        System.out.println("zle");
                        hp = hp + pc;
                        System.out.println("hp wzroslo o " + pc);
                }
            }

        } while (hp > 0);

        System.out.println("pokonany");
        sc.close();
    }
}

关键修改点说明

  • 取消定时任务:无论用户是否按时输入,都调用zd.cancel()和czas.cancel(),彻底终止已调度的任务,防止它在后台执行干扰流程。
  • 超时逻辑处理:通过计时判断用户输入状态,同时在TimerTask中标记超时并关闭输入流,解除Scanner的阻塞,让循环能正常进入下一轮。
  • 重置Scanner:超时后重新创建Scanner,避免因输入流关闭导致后续无法读取输入的问题。

内容的提问来源于stack exchange,提问作者DraggyCords cords

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 15:01:11