ScheduledThreadPoolExecutor任务从队列中删除

时间:2016-06-21 10:43:33

标签: java multithreading

我有一个具有固定延迟的任务,并希望在c.Children = carrierList.Where(child => child.ParentCarrierId == c.CarrierId).ToList(); CarrierId = 1 | |__________________ CarrierId = 2 | |__________________ CarrierId = 3 | |___________________ CarrierId = 4 | CarrierId = 2 | CarrierId = 3 | CarrierId = 4 | CarrierId = 5 的队列中只有一个任务。我的想法是使用ScheduledThreadPoolExecutor来检查队列中是否只有一个任务。

我知道任务仍然在队列中,直到固定延迟。我需要确切地知道什么时候从队列中删除任务。我假设当任务开始执行runnable命令时它被删除。但是我找不到任何说明那么准确的规范。

这是我设想的代码:

getQueue().isEmpty()

所以这样只能在队列中安排一个任务。

1 个答案:

答案 0 :(得分:1)

请考虑以下事项:

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 检查与已安排/正在运行的任务的冲突。如果检测到与另一个预定/正在运行的任务发生冲突,则不会安排其他任务。