在比赛期间在后台运行计数器线程

时间:2014-09-27 21:01:24

标签: java multithreading

我想知道在玩游戏时让计时器在后台运行的最佳方法。

我正在编写一个HiLo游戏版本(用Java编写),它为用户提供了一定的时间来确定一个数字。如果猜测不正确,游戏将告诉用户名称是太高还是太低。

我正在使用System.currentTimeMillis()跟踪时间并查看已经过了多长时间。这似乎运作良好,到目前为止,我一直在检查每次输入新号码时已经过了多少时间。例如,目前app输出如下所示:

  Welcome to HiLo! 
  You have 10 seconds to guess a number I'm thinking of between 1 and 100.

  > 67 
  Too high.

  > 29
   Too low.

  Half of your time is gone! Only 5 seconds remains!

  > 37
  Too high.

  > 33

  Oops! Time is up - try again.

如您所见,目前,它只能检查我输入新号码的时间。

我已经尝试创建一个以定时器启动的线程,但是,当我启动它时,它会一直计数直到时间耗尽,而不会继续执行thread.run(int guess),当有一个新的猜测。我希望能在计数器运行时仍然猜测。这是我尝试thread.start()的新实现:

public void start(int time_sent) throws InterruptedException {
    time = time_sent; 

    startTime = (System.currentTimeMillis() / 1000);

    while (1==1) {
        long elapsed = ((System.currentTimeMillis() / 1000) - (startTime));
        if (elapsed >= (time)) {
            System.out.println("Oops! Time is up - try again.");
            System.exit(0);
        }
        else if (elapsed >= (time/2) && !halfWarning) {
            System.out.println("Half of your time is gone! Only " + (time/2) + " seconds remains!");
            halfWarning = true;
        }
    }

}

如何在后台继续运行此计数器?

4 个答案:

答案 0 :(得分:1)

使用ScheduledExecutorService来执行以后的并发操作:

ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
ScheduledFuture<?> half = ses.schedule(new Runnable() {
    @Override
    public void run() {
        System.out.println("Half of your time is gone!");
    }
}, time / 2, TimeUnit.SECONDS);
ScheduledFuture<?> full = ses.schedule(new Runnable() {
    @Override
    public void run() {
        System.out.println("Oops! Time is up - try again.");
        // System.exit(0) ?
    }
}, time, TimeUnit.SECONDS);

// check
if (input == toGuess) {
    half.cancel();
    full.cancel();
}

答案 1 :(得分:1)

这是另一种方法:

public void game() {

    Scanner scanner = new Scanner(System.in);

    int time = 10; // sec

    message("You have " + time + " seconds to guess...");
    new Thread(new Background(System.currentTimeMillis() / 1000, time)).start();

    while (true) {
        String s = scanner.next();

        if (s.equals("55")) {
            message("You win");
            System.exit(0);
        } else {
            message("try again...");
        }
    }

}

private void message(String str) {
    System.out.println(str);
    System.out.print("> "); // monit
}

使用Background类中实现的行为启动1个线程。接下来,输入while循环以捕获用户输入。后台线程在后台工作......

private class Background implements Runnable {

    private long startTime;
    private long time;
    private boolean halfWarning;

    private Background(long startTime, long time) {
        this.startTime = startTime;
        this.time = time;
    }

    @Override
    public void run() {

        while (true) {
            long now = System.currentTimeMillis() / 1000;
            long elapsed = now - startTime;

            if (elapsed >= (time / 2) && !halfWarning) {
                message("\n Half of your time is gone! Only " + (time / 2) + " seconds remains!");
                halfWarning = true;
            }

            if (elapsed >= time) {
                message("\n Oops! Time is up - try again.");
                System.exit(0);
            }

            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                //ignore
            }
        }
    }
}

答案 2 :(得分:0)

你可以有一个Timer线程打印出这些消息并关闭监听程序。

答案 3 :(得分:0)

它可能会激励你:

public static class Game extends TimerTask {
    private long    start;
    private long    end;

    public Game(long end) {
        super();
        this.start = System.currentTimeMillis();
        this.end = end;
    }

    @Override
    public void run() {
        while (System.currentTimeMillis() - start < end)
            System.out.println(System.currentTimeMillis());
    }
}

public static void main(String[] args) {
    TimerTask task = new Game(10000);
    Timer timer = new Timer();
    timer.schedule(task,0);
}