gpt4 book ai didi

java - 确定 ScheduledExecutorService 下次触发的时间

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:25:51 25 4
gpt4 key购买 nike

有没有办法确定 ScheduledExecutorService 下一次触发的当前毫秒数或其他时间度量?

scheduleTaskExecutorUpdate = Executors.newSingleThreadScheduledExecutor();

我有一个运行时间较长的 ScheduledExecutorService(A) 和一个运行时间较短的 ScheduledExecutorService(B) 我想更新一个 TextView,显示 的倒计时>ScheduledExecutorService(A) 将在接下来触发。

最佳答案

如果您跟踪 ScheduledFuture s 用于执行程序安排的所有任务,然后是。这变成了确定下一个任务必须触发之前的最小延迟的问题,这应该是一个相当可靠的估计。

final Collection<ScheduledFuture<?>> futures = ...;
/* for each schedule, add it to the above collection */
...
final long delay = Collections.min(futures).getDelay(TimeUnit.MILLISECONDS);

...或者,对于一项任务,您只需执行以下操作:

final ScheduledFuture<?> future = ...;
final long delay = future.getDelay(TimeUnit.MILLISECONDS);

现在,如果您打算很多,有多个任务,我建议您维护一个DelayQueue .但是,您不能仅仅将 ScheduledFuture 放入队列中而不维护由周期性任务引起的更改。幸运的是,类ScheduledThreadPoolExecutor应该通过其 decorateTask 很好地处理这个问题方法。

请注意,这意味着您需要直接创建自己的ScheduledThreadPoolExecutor。像下面这样的东西可能会起作用。

public class TrackingSingleThreadScheduledExecutor
extends ScheduledThreadPoolExecutor {

private final DelayQueue<ScheduledFuture<?>> tasks
= new DelayQueue<RunnableScheduledFuture<?>>();

public TrackingSingleThreadScheduledExecutor() {
super(1);
}

public DelayQueue<? extends ScheduledFuture<V>> tasks() {
return tasks;
}

public ScheduledFuture<V> next() {
return tasks.peek();
}

protected <V> RunnableScheduledFuture<V> decorateTask
(final Callable<V> callable, final RunnableScheduledFuture<V> task) {
return new QueueAwareTask(task);
}

protected <V> RunnableScheduledFuture<V> decorateTask
(final Runnable runnable, final RunnableScheduledFuture<V> task) {
return new QueueAwareTask(task);
}

private final class QueueAwareTask<V> implements RunnableScheduledFuture<V> {

private final RunnableScheduledFuture<V> inner;

public QueueAwareTask(final RunnableScheduledFuture<V> inner) {
this.inner = inner;
}

public boolean isPeriodic() {
return inner.isPeriodic();
}

public long getDelay(final TimeUnit unit) {
return inner.getDelay(unit);
}

public void run() {
inner.run();
if (queue.remove(inner) && inner.isPeriodic()
&& !inner.isCancelled()) {
queue.add(inner);
}
}

public int compareTo(final Delayed other) {
return inner.compareTo(other);
}

public boolean cancel(final boolean mayInterruptIfRunning) {
final boolean cancelled = inner.cancel(mayInterruptIfRunning);
if (cancelled) {
queue.remove(inner);
}
return cancelled;
}

public boolean isCancelled() {
return inner.isCancelled();
}

public boolean isDone() {
return inner.isDone();
}

public V get() throws InterruptedException, ExecutionException {
return inner.get();
}

public V get(final long timeout, final TimeUnit unit)
throws InterruptedException, ExecutionException {
return inner.get(timeout, unit);
}
}
}

那么,用法如下。

final TrackingSingleThreadScheduledExecutor executor
= new TrackingSingleThreadScheduledExecutor();
...
final long delay = executor.next().getDelay(TimeUnit.MILLISECONDS);

关于java - 确定 ScheduledExecutorService 下次触发的时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12222474/

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