在一定时间后禁用扫描仪

时间:2016-10-09 21:24:12

标签: java multithreading timing

我正在制作一个基于文本的测验,我希望这样做,以便如果玩家在一定时间后没有回答,那么就好像他们的问题错了。我真的不确定如何做到这一点。我有一些想法:多线程和计时器;但是我不知道怎么做。

其中任何一个都是不错的选择吗?

带问题的方法:

    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;
    }
}

2 个答案:

答案 0 :(得分:0)

使用Timer类(java.util.Timer)也是多线程的。虽然多线程可能会引入大量可能的陷阱,但它似乎确实适合这样的应用程序。您可以创建一个Timer,然后在问题开头安排TimerTask,标记一些标记以指示问题不正确并禁用接受未来的答案尝试(或继续下一个问题或其他当计划任务发生时,动作是适当的。这将需要创建TimerTask的子类,该子类实现抽象run()方法以执行您想要的操作(标记问题不正确等)。您甚至可能希望将计时器用于其他任务(例如,让用户有时间处理他们在问题上超时的事实,然后再转到下一个)。

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

的更多细节

但是,您需要注意竞争条件等陷阱(例如,如果您的任务是标记问题不正确,然后禁用它的答案,如果用户要回答您的任务之间的问题标记错误并禁用回答它可能会出现意外行为)。这是编写多线程代码的常见挑战之一。如果您的整体程序逻辑和流程足够简单,那么仔细设计任务执行的操作时间和顺序可能足以避免这些问题,但是在处理从不同线程到共享部分的更新时应该非常谨慎状态(例如更新一个布尔值,表明问题是从定时器任务中得到纠正或不正确)。

更一般的多线程肯定是可用的,尽管Timer似乎很有用,因为它更特定于这种特殊的任务。

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

答案 1 :(得分:0)

您可以按照与基于在一定时间后执行操作的任何其他操作相同的方式执行此操作,其中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
}