一定时间后禁用扫描仪

Disabling a scanner after a certain amount of time

我正在做一个基于文本的测验,我想这样做,如果玩家在一定时间后没有回答,那么它就会表现得好像他们答错了问题。我不太确定该怎么做。我有几个想法: 多线程和定时器;但是我也不知道该怎么做。

这两个都是好的选择吗?

我问题的方法:

    public void questionOneA(String choice) {

    choice = scanner.nextLine();
    setWrong(false);

    switch(choice) {
    case "a":
        setLives(lives - 1);
        setWrong(true);

        if (getLives() > 0) {
            System.out.println("WRONG! Try again.");
        }
        else {
            System.out.println("WRONG!");
        }
        break;
    case "b":
        System.out.println("CORRECT!");
        setCorrect(true);
        break;
    case "c":
        setLives(lives - 1);
        setWrong(true);

        if (getLives() > 0) {
            System.out.println("WRONG! Try again.");
        }
        else {
            System.out.println("WRONG!");
        }
        break;
    case "d":
        setLives(lives - 1);
        setWrong(true);

        if (getLives() > 0) {
            System.out.println("WRONG! Try again.");
        }
        else {
            System.out.println("WRONG!");
        }
        break;
    case "skip":
        if (skips > 0) {
            setSkips(skips - 1);
            setCorrect(true);
        }

        else {
            System.err.println("You do not have any skips left!");
        }
        break;
    default:
        System.err.println("Please type an answer.");
        break;
    }
}

使用Timerclass(java.util.Timer)也是多线程。它似乎确实适合这样的应用程序,尽管多线程可能会引入大量可能的陷阱。您可以创建一个 Timer 然后在问题的开头安排一个 TimerTask 来标记一些标志以指示问题不正确并禁止接受未来的回答尝试(或继续下一个问题或其他action is appropriate) 当预定任务发生时。这将需要创建一个 TimerTask 的子 class 来实现抽象 run() 方法来执行您想要的操作(将问题标记为不正确等)。您甚至可能希望将计时器用于其他任务(例如给用户一些时间来处理他们在继续下一个问题之前超时的事实)。

使用 Timer 的基本流程(如上例所示)是创建 TimerTask 的子 class 实现 run() 以执行任何任务应该在某个时间或某个持续时间结束时发生(或以某个间隔重复,Timers 也支持)。然后实例化一个 Timer 并安排这个 TimerTask subclass 的实例在某个时间或在某个时间间隔后执行(取决于 Timerschedule 方法你打电话来安排它)。然后,一旦达到该时间或间隔已过,您实现的 run() 方法将在 Timer 的后台线程中调用。有关 Timer

的更多细节

但是,您需要注意竞态条件等陷阱(例如,如果您的任务是将问题标记为不正确然后禁用答案,如果用户要在您的任务之间回答问题将其标记为不正确并禁止回答它可能会出现意外行为)。这是编写多线程代码的常见挑战之一。如果您的整体程序逻辑和流程足够简单,仔细设计任务在何时以何种顺序执行哪些操作可能足以避免这些问题,但在处理从不同线程到共享部分的更新时应格外小心状态(例如更新布尔值,指示问题是否正确来自计时器任务)。

当然可以使用更通用的多线程,尽管 Timer 似乎很有用,因为它更特定于这种特定类型的任务。

除此之外(尽管非常相关),我强烈警告不要为每个单独的问题编写完整的方法,从风格上讲,因为它可能导致大量重复或非常相似的代码。相反,为问题创建 class 之类的方法(尤其是如果您的所有问题都具有相似的格式)可能更可取,它允许您(例如)通过简单地调用带有问题文本的构造函数来创建新问题正确答案的索引。您的问题 class 可能包含一种方法,该方法在您的示例代码中执行答案检查,所有问题(如 class 实例)都有,而您无需为每个问题重写它。

你可以像对待其他任何基于在一定时间后做某事的方法一样来做,用 TimerDelta-time loop 触发一个事件(在这种情况对应于在一定的(delta-)时间后将问题弄错)。

假设您的测验循环运行(就像游戏和类似游戏的软件一样),那么您需要做的就是:

//Specify a maximum time and record it in a variable; in this case, I'm using milliseconds as unit, and 30 seconds of time.
long maxQuestionTime = 30000;

//Outside the game-loop, at start of a question, record a timestamp of the current time + max time.
long maxQuestionTimestamp = System.currentTimeMillis()+maxQuestionTime;

//Inside game-loop, check if current time has gone above the timestamp, effectively measuring elapsed time.
if(System.currentTimeMillis()>maxQuestionTimestamp){
    //fail the question here
}