gpt4 book ai didi

java - 从计时器线程调用 java 计时器任务

转载 作者:行者123 更新时间:2023-12-01 10:25:15 25 4
gpt4 key购买 nike

这是关于java内置的Timer类。我需要一个以一定的设定时间间隔频繁调用的方法,但如果执行时间太长,我不希望它们堆积起来,因此解决方案是在所述方法的开头对下一次执行进行排队。当然,这意味着排队发生在同一个队列线程中。这会成功还是会导致问题?

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

}

最佳答案

Java 具有执行器服务来准确地完成您想做的事情。看看方法ScheduledExecutorService#scheduleWithFixedDelay() 。与方法 ScheduledExecutorService#scheduleAtFixedRate() 相反,具有固定延迟的方法不会尝试跟上。

这是一个例子:

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

public void task() {
// run your task
}
<小时/>

确实,标准库方法似乎未涵盖您的用例。但是,您应该能够使用以下类来执行您想要的操作。

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

由于它使用单线程执行器服务,因此在上一个执行完成之前,它不会开始下一个执行。此外,它会在任务本身执行之前安排下一次执行。

另请参阅this SO-关于为什么您应该更喜欢执行器服务而不是 Timer 类的问题。

你还是要自己实现关闭机制。

关于java - 从计时器线程调用 java 计时器任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35386052/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com