gpt4 book ai didi

java - ScheduledThreadPoolExecutor 任务从队列中移除

转载 作者:行者123 更新时间:2023-12-01 09:46:45 28 4
gpt4 key购买 nike

我有一个具有固定延迟的任务,并且希望在 ScheduledThreadPoolExecutor 队列中只有一个任务。我的想法是使用 getQueue().isEmpty() 来检查队列中是否只有一个任务。

我知道任务会保留在队列中,直到固定延迟为止。我需要确切地知道任务何时从队列中删除。我假设当任务开始执行可运行命令时它被删除。但是我找不到任何具体说明的规范。

这是我设想的代码:

if (task.getQueue().isEmpty()){
task.schedule(new Runnable() {
@Override
public void run(){
// do my awesome stuff
}
}, FIXED_DELAY, TimeUnit.MILLISECONDS);
}

这样一来队列中只能调度一个任务。

最佳答案

考虑以下因素:

publicinterface ConflictingRunnable extends Runnable {
boolean hasConflicts(Runnable other);
}

还有

public class ConflictAwareScheduledThreadPoolExecutor {

private final Map<Runnable, ScheduledFuture> scheduledRunnables = new HashMap<>();

private final ScheduledThreadPoolExecutor executor;

public ConflictAwareScheduledThreadPoolExecutor(final ScheduledThreadPoolExecutor executor) {
this.executor = executor;
}

public ScheduledFuture<?> schedule(Runnable command,
long delay,
TimeUnit unit) {
if (command instanceof ConflictingRunnable) {
final ConflictingRunnable conflictingRunnable = (ConflictingRunnable) command;
for (final Iterator<Runnable> itt = scheduledRunnables.keySet().iterator(); itt.hasNext(); ) {
final Runnable scheduledRunnable = itt.next();
final ScheduledFuture<?> scheduledFuture = scheduledRunnables.get(scheduledRunnable);
if (scheduledFuture.isDone()) {
itt.remove();
} else if (conflictingRunnable.hasConflicts(scheduledRunnable)) {
return null;
}
}
}
final ScheduledFuture<?> t = this.executor.schedule(command, delay, unit);
scheduledRunnables.put(command, t);
return t;
}
}

当你运行时:

public class ScheduledTest {

public static void main(String[] args) throws InterruptedException {
final ScheduledThreadPoolExecutor scheduler = new ScheduledThreadPoolExecutor(1);
final ConflictAwareScheduledThreadPoolExecutor conflictAwareScheduler = new ConflictAwareScheduledThreadPoolExecutor(scheduler);

for (int i = 0; i < 100; i++) {
conflictAwareScheduler.schedule(new MyTask(i), 100, TimeUnit.MILLISECONDS);
Thread.sleep(10);
}

scheduler.shutdown();
}

private static class MyTask implements ConflictingRunnable {

private final int i;

public MyTask(final int i) {
this.i = i;
}


@Override
public boolean hasConflicts(Runnable other) {
return other instanceof MyTask;
}

@Override
public void run() {
System.out.println(">>> " + i);
}
}
}

你会得到类似的东西:

>>> 0
>>> 11
>>> 21
>>> 31
>>> 42
>>> 53
>>> 64
>>> 75
>>> 86
>>> 97

ConflictAwareScheduledThreadPoolExecutor 检查与已计划/正在运行的任务是否存在冲突。如果检测到与另一个计划/正在运行的任务有冲突,则不会计划其他任务。

关于java - ScheduledThreadPoolExecutor 任务从队列中移除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37942261/

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