是否有代码来检查计时器是否正在运行?

2022-09-04 19:18:26

我有一个游戏,我正在安排一个计时器。我有这个CoresManager文件:

package com.rs.cores;

 import java.util.Timer;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;

 public final class CoresManager {

protected static volatile boolean shutdown;
public static WorldThread worldThread;
public static ExecutorService serverWorkerChannelExecutor;
public static ExecutorService serverBossChannelExecutor;
public static Timer fastExecutor;
public static ScheduledExecutorService slowExecutor;
public static int serverWorkersCount;

public static void init() {
    worldThread = new WorldThread();
    int availableProcessors = Runtime.getRuntime().availableProcessors();
    serverWorkersCount = availableProcessors >= 6 ? availableProcessors - (availableProcessors >= 12 ? 7 : 5) : 1;
    serverWorkerChannelExecutor = availableProcessors >= 6 ? Executors
            .newFixedThreadPool(availableProcessors - (availableProcessors >= 12 ? 7 : 5),
            new DecoderThreadFactory()) : Executors.newSingleThreadExecutor(new DecoderThreadFactory());
    serverBossChannelExecutor = Executors
            .newSingleThreadExecutor(new DecoderThreadFactory());
    fastExecutor = new Timer("Fast Executor");
    slowExecutor = availableProcessors >= 6 ? Executors.newScheduledThreadPool(availableProcessors >= 12 ? 4 : 2,
                    new SlowThreadFactory()) : Executors
            .newSingleThreadScheduledExecutor(new SlowThreadFactory());
    worldThread.start();
}

public static void shutdown() {
    serverWorkerChannelExecutor.shutdown();
    serverBossChannelExecutor.shutdown();
    fastExecutor.cancel();
    slowExecutor.shutdown();
    shutdown = true;
}

private CoresManager() {

}
}

我在游戏中使用它:

    private void startTimer() {
    CoresManager.fastExecutor.scheduleAtFixedRate(new TimerTask() {
        @Override
        public void run() {
            if (timer == 0 || timer < 1) {
                player.sm("Your timer has ended! The NPCs will no longer spawn.");
                timer = 0;
                this.cancel();
                exitInstance(); 
                return;
            }
            timer--;
            timerchecker = true;
            seconds = timer % 60;
            player.setTimer(timer);
            minutes = TimeUnit.SECONDS.toMinutes(timer);            
        }
    }, 0, 1000);
}

如果玩家注销并且服务器重新启动,则 CoresManager 计时器将停止运行。为了让它再次运行,我添加了一个代码,让它在你重新登录后再次执行startTimer()。但是,由于如果服务器未注销,计时器仍会运行,因此计时器将开始运行两次。计时器开始减去 2 或更多,具体取决于您注销和进入的次数。我认为如果有代码来确定计时器是否已经在运行,它将修复。有没有办法做到这一点?请帮忙!


答案 1

我在文档中没有看到任何提供检查TimerTask对象(http://docs.oracle.com/javase/1.5.0/docs/api/java/util/TimerTask.html)状态的内容,因此一种选择是扩展TimerTask并创建自己的类。您可以使用匿名的TimerTask,而是创建如下内容:

public class CoresTimerTask extends TimerTask {

    private boolean hasStarted = false;

    @Overrides
    public void run() {
        this.hasStarted = true;
        //rest of run logic here...
    }

    public boolean hasRunStarted() {
        return this.hasStarted;
    }
}

并且只需维护对此CoresTimerTask对象的引用,然后将其传递到startTimer()中。然后,您可以稍后通过 hasRunStarted 检查此对象。


答案 2

公共长计划执行时间()

返回此任务最近实际执行的计划执行时间。(如果在任务执行过程中调用此方法,则返回值是正在进行的任务的计划执行时间 如果任务尚未开始其首次执行,则返回值未定义。

此方法通常不与固定延迟执行重复任务结合使用,因为它们的计划执行时间允许随时间而变化,因此不是非常重要。

  1. 第一件事定期运行任务需要设置/重置状态标志
  2. 第二(当我看例子时)最好密封这种类型的类

但如果有人坚持要有这样的方法

   public abstract class NonInterruptableTask extends TimerTask {

        protected boolean isDone = false;

        public boolean isDone() {return isDone;}

        protected abstract void doTaskWork();

        @Override
        public void run() {
            isDone = false;
            doTaskWork();
            isDone = true;
        }

  }

用法:

  TimerTask myTask = new NonInterruptableTask() {

       @Override 
       public void doTaskWork() {

          //job here 
       }
  };