在时间限制内猜数字[主题]

时间:2017-11-18 04:23:34

标签: java multithreading

我一直在练习线程,所以我写了这个定时游戏,用户需要猜出正确的数字(范围从1-10)。如果用户在时间限制内猜出正确答案,则线程停止并且程序终止。当用户未能在时间限制内猜测时,它无法工作。即使它在时间限制之后进入if语句,它仍然无法完全中断线程,除非我猜错了正确的数字。我已阅读其他主题,但他们似乎使用了关于“传统”猜谜游戏或使用Timer的问题。还应该理解建议解决方案的解释和/或提示。

    import java.util.*;
    import static java.lang.System.out;
    import java.io.*;

    public class Threading implements Runnable {
        private static int num;
        private static int k;

    public void run() {
        try {
            Scanner line = new Scanner(System.in);
            k = -1;
            out.println("Guess!");
            while (k != num) {
                k = line.nextInt();
                if (k != num) {
                    out.println("Nope");
                }
            }

        } 
        catch (Exception e) {
            out.println("I'm not done!");
        }
    }

    public static void main(String args[]) throws InterruptedException {

        num = (int) (Math.random() * 9 + 1);
        out.println(num);
        Thread t = new Thread(new Threading());
        t.start();

        long patience = 1000 * 5;
        long startTime = System.currentTimeMillis();
        while (t.isAlive()) {
            t.join(1000);
            if (((System.currentTimeMillis() - startTime) > patience) && t.isAlive()) {
                out.println("I'm in here!");
                t.interrupt();
                t.join();
                out.println("Times up!");
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

由于其中一条评论已经指出对nextInt的调用会阻止,我认为没有必要详细说明。

所以现在我假设你在计时器到期后允许用户1最后猜测你没事。

以下是修改后的代码,包括我的评论。我将您命名为t的线程称为“猜测线程”。

private static int num;
private static int k;
//Changed variable "line" to "scanner" and made it static so that the
//  main method can close it once everything is done.
private static Scanner scanner = new Scanner(System.in);

public void run() {
    try {
        k = -1;
        System.out.println("Guess!");
        while (k!=num) {
            //Added a check for interrupt, otherwise this thread will never 
            // end unless the user enters the correct answer.
            if(Thread.currentThread().isInterrupted())
                return;
            k = scanner.nextInt();
            if(k != num){
                System.out.println("Nope");
            }
        }
        System.out.println("Correct!");

    } catch (Exception e) {
        System.out.println("I'm not done!");
    }
}

public static void main(String args[]) throws InterruptedException {

    num = (int) (Math.random() * 9 + 1);
    System.out.println(num);
    //Declared the guessing thread as final so it can be used inside of
    // the TimerTask that is created later.
    final Thread t = new Thread(new GuessUntilTimeLimit());
    t.start();

    long patience = 1000 * 5;

    //Use a Timer to enforce your time limit, the TimerTask will execute
    // an interrupt of your guessing thread if the thread is still alive
    // (it may have died already if user got right answer)
    Timer timer = new Timer();
    TimerTask task = new TimerTask(){

        @Override
        public void run() {
            if(t.isAlive()){
                t.interrupt();
                System.out.println("Times up! Enter your final guess now.");
            }               
        }
    };
    timer.schedule(task, patience);
    //Wait for the guessing thread to finish before canceling the timer
    t.join();
    //By now either the user got the answer or time has run out. Either way
    //  we need to clean up by canceling the timer.
    timer.cancel();
    //Added a call to close the scanner, it's always important to release
    // resources
    scanner.close();
}

现在你的主线程schedules a task将在patience毫秒后执行。然后,该任务负责interrupting“猜测线程”。 “猜测线程”将检查interrupt并在适当时自行停止。

同样,根据您的要求,您可能需要更改接受用户输入的方式,因为nextInt将阻止该线程。为了完整起见,我提供了评论中提到的question regarding interrupting Scanner.nextLine的链接。