gpt4 book ai didi

java - 使用 ExecutorService 控制任务执行顺序

转载 作者:IT老高 更新时间:2023-10-28 21:03:47 25 4
gpt4 key购买 nike

我有一个将异步任务委托(delegate)给线程池的进程。我需要确保某些任务按顺序执行。比如

任务按顺序到达

任务 a1、b1、c1、d1、e1、a2、a3、b2、f1

任务可以按任何顺序执行,除非存在自然依赖关系,因此必须按该顺序处理 a1、a2、a3,方法是分配给同一个线程或阻塞这些线程,直到我知道前一个 a# 任务已完成。

目前它不使用 Java Concurrency 包,但我正在考虑更改以利用线程管理。

有没有人有类似的解决方案或如何实现这一点的建议

最佳答案

我编写了自己的 Executor 来保证具有相同键的任务的任务排序。它使用队列映射来处理具有相同键的订单任务。每个键控任务使用相同的键执行下一个任务。

此解决方案不处理 RejectedExecutionException 或委托(delegate)执行器的其他异常!所以委派的Executor应该是“无限的”。

import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.Executor;

/**
* This Executor warrants task ordering for tasks with same key (key have to implement hashCode and equal methods correctly).
*/
public class OrderingExecutor implements Executor{

private final Executor delegate;
private final Map<Object, Queue<Runnable>> keyedTasks = new HashMap<Object, Queue<Runnable>>();

public OrderingExecutor(Executor delegate){
this.delegate = delegate;
}

@Override
public void execute(Runnable task) {
// task without key can be executed immediately
delegate.execute(task);
}

public void execute(Runnable task, Object key) {
if (key == null){ // if key is null, execute without ordering
execute(task);
return;
}

boolean first;
Runnable wrappedTask;
synchronized (keyedTasks){
Queue<Runnable> dependencyQueue = keyedTasks.get(key);
first = (dependencyQueue == null);
if (dependencyQueue == null){
dependencyQueue = new LinkedList<Runnable>();
keyedTasks.put(key, dependencyQueue);
}

wrappedTask = wrap(task, dependencyQueue, key);
if (!first)
dependencyQueue.add(wrappedTask);
}

// execute method can block, call it outside synchronize block
if (first)
delegate.execute(wrappedTask);

}

private Runnable wrap(Runnable task, Queue<Runnable> dependencyQueue, Object key) {
return new OrderedTask(task, dependencyQueue, key);
}

class OrderedTask implements Runnable{

private final Queue<Runnable> dependencyQueue;
private final Runnable task;
private final Object key;

public OrderedTask(Runnable task, Queue<Runnable> dependencyQueue, Object key) {
this.task = task;
this.dependencyQueue = dependencyQueue;
this.key = key;
}

@Override
public void run() {
try{
task.run();
} finally {
Runnable nextTask = null;
synchronized (keyedTasks){
if (dependencyQueue.isEmpty()){
keyedTasks.remove(key);
}else{
nextTask = dependencyQueue.poll();
}
}
if (nextTask!=null)
delegate.execute(nextTask);
}
}
}
}

关于java - 使用 ExecutorService 控制任务执行顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2153663/

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