两个计时器互相调用

two timers calling each other

我有两个来自 java.util.Timer class 的计时器。计时器达到条件并启动另一个计时器,并在启动另一个计时器之前停止原始计时器。这可以追溯到更进一步,如下所示:

private void StartGame() 
{
    RankTimer.cancel();
    InGame = true;
    timeLeft = GamePeriod;
    InGameTimer.purge();
    InGameTimer.schedule(new TimerTask() {

        @Override
        public void run() 
        {
            timeLeft = timeLeft-timerUpdate;
            if(timeLeft<=0)
            {
                StartRank();
            }
        }
    }, 0, timerUpdate);

}
protected void StartRank() 
{

    InGameTimer.cancel();
    GameDataChange();
    InGame = false;
    timeLeft = RankPeriod;
    RankTimer.purge();
    RankTimer.schedule(new TimerTask() {

        @Override
        public void run() 
        {
            timeLeft = timeLeft-timerUpdate;
            if(timeLeft<=0)
            {
                StartGame();
            }
        }
    }, 0, timerUpdate);
}

计时器是 RankTimer 和 InGameTimer。虽然代码在某个时候 运行ning 我收到以下错误:

线程中出现异常 "Timer-0" java.lang.IllegalStateException:计时器已取消。 在 java.util.Timer.sched(未知来源) 在 java.util.Timer.schedule(未知来源) 在 demo.ServerGameThread.StartRank(ServerGameThread.java:76) 在 demo.ServerGameThread$1.run(ServerGameThread.java:64) 在 java.util.TimerThread.mainLoop(未知来源) 在 java.util.TimerThread.运行(未知来源)

我在设置调度程序之前也进行了清除。这个想法是这些计时器将 运行 无限地相互调用,同时启动它们自己的任务。任何想法为什么会失败?或者有更好的方法来实现我想要做的事情吗?

我意识到我可以只用一个计时器做我想做的事情:

    private void StartGame() 
{
    InGame = true;
    InGrace = false;
    timeLeft = GamePeriod + GracePeriod + RankPeriod;

    GameTimer.schedule(new TimerTask() {

        @Override
        public void run() 
        {
            timeLeft = timeLeft-timerUpdate;
            if(timeLeft<=GracePeriod + RankPeriod && timeLeft>RankPeriod)
            {
                InGrace = true;
            }
            else if(timeLeft<=RankPeriod && timeLeft>0)
            {
                GameDataChange();
                InGame = false;
                InGrace = false;
            }
            else if(timeLeft<=0)
            {
                InGame = true;
                timeLeft = GamePeriod + GracePeriod + RankPeriod;
            }
        }
    }, 0, timerUpdate);

我添加了 GracePeriod 部分,它与之前的代码没有太大区别。我只是将 timeLeft 变量重置为其初始起始值以再次开始循环。