从计时器线程调用 java Timer-Task [英] Invoking a java Timer-Task from the timer thread

查看:57
本文介绍了从计时器线程调用 java Timer-Task的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是关于java内置的Timer-class.我需要一个方法在某些设置的时间间隔内被频繁调用,但是如果执行时间太长,我不希望它们堆积起来,所以解决方案是在所述方法的开始处排队下一次执行.当然这意味着排队发生在同一个队列Thread中.这会奏效还是会导致问题?

This is about java's built-in Timer-class. I need a method to be invoked frequently at certain set intervals, but if the execution takes too long, I don't want them to pile up, so the solution would be to queue up the next execution at the beginning of said method. Of course this means that the queueing happens in the same queue Thread. Would this work out or would this cause problems?

public class SomeClass extends TimerTask {
   public static SomeClass timer;
   public void run() {
      timer.schedule(this,100);
      //do stuff
   }

}

推荐答案

Java 具有执行程序服务,可以完全按照您的意愿执行操作.看看方法 ScheduledExecutorService#scheduleWithFixedDelay().与方法 ScheduledExecutorService#scheduleAtFixedRate(),固定延迟的方法不尝试跟上.

Java has the executor services to do exactly what you want to do. Have a look at the method ScheduledExecutorService#scheduleWithFixedDelay(). As opposed to the method ScheduledExecutorService#scheduleAtFixedRate(), the method with fixed delay does not try to keep up.

这是一个例子:

public void run() {
    Executors.newSingleThreadScheduledExecutor().scheduleWithFixedDelay(
            this::task, 0, 10, TimeUnit.MILLISECONDS);
}

public void task() {
    // run your task
}

<小时>

确实,标准库方法似乎没有涵盖您的用例.但是,您应该能够使用以下类来做您想做的事情.


Indeed, your use case seems to be not covered by the standard library methods. However, you should be able to use the following class to do what you want.

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

public class TimerExample {
    private final ScheduledExecutorService executor = Executors
            .newSingleThreadScheduledExecutor();
    private final Runnable task;
    private final Consumer<Exception> onException;
    private final long delay;
    private final TimeUnit unit;

    public TimerExample(Runnable task, Consumer<Exception> onException,
            long delay, TimeUnit unit) {
        this.task = task;
        this.onException = onException;
        this.delay = delay;
        this.unit = unit;
    }

    public void start() {
        executor.execute(this::execute);
    }

    private void execute() {
        executor.schedule(this::execute, delay, unit);
        try {
            task.run();
        } catch (Exception e) {
            onException.accept(e);
        }
    }
}

这里的用法:

    new TimerExample(() -> System.out.println("."),
            Exception::printStackTrace, 20, TimeUnit.MILLISECONDS).start();

由于它使用的是单线程执行器服务,所以直到上一次执行完成后才会开始下一次执行.此外,它会在任务本身执行之前安排下一次执行.

Since it uses a single threaded executor service, it will not start the next execution until the previous is finished. Also, it schedules the next execution before the task itself is executed.

此外,请参阅 this SO-question 关于为什么您应该更喜欢 executor 服务的原因定时器类.

Also, see this SO-question about why you should prefer the executor services above the Timer class.

你仍然需要自己实现关闭机制.

You still have to implement the shutdown mechanism by yourself.

这篇关于从计时器线程调用 java Timer-Task的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆