java 使用 ScheduledExecutorService 创建计时器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13024787/
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-10-31 11:12:45  来源:igfitidea点击:

Creating a timer with ScheduledExecutorService

javamultithreading

提问by echew

So I'm trying to figure out how to create a timer, I came across this: using ScheduledExecutorService to start and stop timer

所以我想弄清楚如何创建一个计时器,我遇到了这个: 使用 ScheduledExecutorService 来启动和停止计时器

The example they have seems to work pretty well. I'm just wondering if I'm utilizing this correctly:

他们的例子似乎工作得很好。我只是想知道我是否正确使用了它:

  public class TimerTest 
{
  private ScheduledExecutorService  es = null;
  private  boolean timeIsUp = false;
  private ScheduledFuture futureHandler = null;
  private  TimeKeeper timeKeeper = null;
  private  String subject = "";
  private  int siteNo;
  private  long time; 
  private  boolean stop;




public  void endTimer()
{
    System.out.println("we should shutdown everything here");
    es.shutdownNow();
}

public  boolean stopTimer()
{

    if (timeKeeper != null)
    {
        timeKeeper.deactivate();
    }
    futureHandler.cancel(true);
 return true;

}
public  boolean isTimeup()
{
    return timeKeeper.isTimeUp();
}
public void startTimer(long mseconds, String subj, int sNo)
{
    subject = subj;
    siteNo = sNo;
    time = mseconds;
    timeKeeper = new TimeKeeper();
    callScheduler(mseconds);

}

public  boolean isTimerRunning()
{
    return (es.isShutdown() || es == null);

}
public void resetTimer(long t)
 {
    stopTimer();
    callScheduler(t);
 }

public  void resetTimer()
{

   resetTimer(time);  
}

private  void callScheduler(long mseconds)
{
    if (es == null)
        es = Executors.newScheduledThreadPool(3);
    timeKeeper = new TimeKeeper();
    futureHandler = es.schedule( timeKeeper, mseconds, TimeUnit.MILLISECONDS);

}


private class TimeKeeper implements Runnable  {
    //volatile for thread-safety

    private volatile boolean isActive = true;  
    private volatile boolean isTimeUp = false;
    public void run ()   {  
        if (isActive){
            callAlert();
            isTimeUp = true;
        }
    }  
    public void deactivate(){
        isActive = false;
    }

    public boolean isTimeUp()
    {
        return isTimeUp;
    }
    private void callAlert()
    {
        System.out.println("you are in the callAlert method");
    }
  }

 }

And here is the Test:

这是测试:

 public static void main(String[] args) {
    // TODO Auto-generated method stub
     long pastTime = System.currentTimeMillis();
     TimerTest timer = new TimerTest();
    timer.startTimer(15000, "bh", 1);
    long time;
    int count =0;
    boolean stop = false;
    while(true)
    {

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        time = System.currentTimeMillis() - pastTime;

        if (time > 3000)
        {
            if (!stop){
                System.out.println("we are reseting the timer");
                timer.resetTimer(4000);

                timer.stopTimer();
                try {
                    Thread.sleep(3995);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                break;

            }
            stop = true;


        }
        if (timer.isTimeup())
        {
            System.out.println("our time is up");
            timer.endTimer();
            break;
        }
        if (!stop)
            System.out.println("hello");
        else
        {
            if (count == 0)
                System.out.println("we wait 10 seconds from now");
            count++;
        }


    }
    timer.resetTimer(1200);
    while (true)
    {
        if (timer.isTimeup())
        {
            timer.isTimeup();
            System.out.println("breaking after time is up");
            break;
        }
    }
    timer.endTimer();

}

This seems to work, I'm might of missed something that I need, this is my first time working with the ScheduledExecutorService Do you guys see any problems with this code? I don't want there to be conflict with thread collision.

这似乎有效,我可能错过了我需要的东西,这是我第一次使用 ScheduledExecutorService 你们看到这段代码有什么问题吗?我不希望与线程冲突发生冲突。

采纳答案by Arham

With ScheduledExecutorServiceyou automatically get the timer feature. You don't need it explicitly unless you have something that the ScheduleExecutorService can't provide. e.g. Let say you want to start a task after initial delay of 10 secs and then subsequent delays of 5 seconds each.

使用ScheduledExecutorService,您会自动获得计时器功能。除非您有 ScheduleExecutorService 无法提供的东西,否则您不需要明确地使用它。例如,假设您想在初始延迟 10 秒后开始任务,然后每次延迟 5 秒。

public void init() {
    executor = new ScheduledThreadPoolExecutor(corePoolSize);
    executor.scheduleWithFixedDelay(new WorkerThread(), 10, 5, TimeUnit.SECONDS);
}

public void end() {
    executor.shutdown();
}