Java 是否有代码可以检查计时器是否正在运行?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28290118/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 05:56:01  来源:igfitidea点击:

Is there a code to check if a timer is running?

javatimer

提问by Zar Qureshi

I have a game where I am scheduling a timer. I have this CoresManager file:

我有一个游戏,我正在安排一个计时器。我有这个 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() {

}
}

I am using this inside the game:

我在游戏中使用它:

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

The CoresManager Timer stops running if the player logs out AND the server gets rebooted. To make it run again, I added a code to make it do startTimer() again once you log back in. However, since the timer still runs if the server didn't log out, the timer starts running twice. The Timer starts getting subtracted by 2, or more, depending on how many times you log out and in. I figure that it would fix if there was a code to determine if the timer is already running. Is there a way to do this? Please help!

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

采纳答案by John D.

I don't see anything in the documentation that provides for checking the status on a TimerTask object (http://docs.oracle.com/javase/1.5.0/docs/api/java/util/TimerTask.html) so one option would be to extend TimerTask and create your own class. Instead of using an anonymous TimerTask, you could create something along the lines of:

我在提供检查 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;
    }
}

and just maintain a reference to this CoresTimerTask object, which you then pass into startTimer(). You can then later check this object via hasRunStarted.

并保持对这个 CoresTimerTask 对象的引用,然后将其传递给 startTimer()。然后您可以稍后通过 hasRunStarted 检查此对象。

回答by ceph3us

public long scheduledExecutionTime()

公共长调度执行时间()

Returns the scheduled execution time of the most recent actual execution of this task. (If this method is invoked while task execution is in progress, the return value is the scheduled execution time of the ongoing task The return value is undefined if the task has yet to commence its first execution.

This method is typically not used in conjunction with fixed-delay execution repeating tasks, as their scheduled execution times are allowed to drift over time, and so are not terribly significant.

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

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

  1. first thing periodically running tasks need set/reset state flag
  2. second (when i look at examples) it is better to seal this type of class
  1. 定期运行任务的第一件事需要设置/重置状态标志
  2. 第二(当我看例子时)最好密封这种类型的类

but if someone insist to have such methods

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

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

  }

usage:

用法:

  TimerTask myTask = new NonInterruptableTask() {

       @Override 
       public void doTaskWork() {

          //job here 
       }
  };

回答by Breno Fachini

you could also declare a boolean state called like "timerstate" or whatever and make it by default to be false. whenever you start a timer you could change this boolean to true and you'd be able to keep track of the timer.

您还可以声明一个名为“timerstate”之类的布尔状态,并使其默认为 false。每当您启动计时器时,您都可以将此布尔值更改为 true,这样您就可以跟踪计时器。

public boolean timerstate;
public Timer t1;


// some code goes here to do whatever you want


if(timerstate == true) {
            t1.cancel();
            t1.purge();
            t1 = new Timer();   
        } else{
            t1.schedule(new TimerTask() {

        @Override
        public void run() {
            timerstate = true;
            //rest of code for the timer goes here
                          }
                      }
          }