我想将任务提交到线程池(或执行服务),但是如果执行器中已经有一个具有相同密钥的任务,则不应同时执行任务。
特别是,这是针对构建工具的,以防止源树的同一部分的任务同时执行。
这是为什么我想要这种行为的一个示例:
public class Example {
public static void main(String[] args) throws Exception {
ExecutorService service = Executors.newFixedThreadPool(2);
Path resource = Paths.get("tmp");
service.submit(() -> {
Files.write(resource, Collections.singleton("foo"));
Thread.sleep(10);
if (!new String(Files.readAllBytes(resource)).equals("foo")) {
System.err.println("someone changed my stuff");
}
return null;
});
service.submit(() -> Files.write(resource, Collections.singleton("bar")));
service.shutdown();
service.awaitTermination(1, TimeUnit.MINUTES);
}
}
答案 0 :(得分:1)
解决方案是为每个密钥使用单独的单线程执行程序。由于可以存在许多密钥,因此为每个密钥创建线程可能会很昂贵,因此我们用轻量级SerialExecutor
代替了单线程执行程序,该行为的行为类似于单线程执行程序,但没有自己的线程,因此需要时,来自某些普通后端执行程序的线程。 JavaDocs of Executor中描述了SerialExecutor
。最佳版本可在我的CodeSamples project
答案 1 :(得分:0)
尝试使用2个不同的执行程序来执行不同类型的任务,如果第一个缓冲池已完成,请再启动一个。
ExecutorService executor1 = Executors.newFixedThreadPool(5);
for (int i = 0; i < 10; i++) {
Runnable worker = new FirstTask("" + i);
executor1.execute(worker);
}
executor1.shutdown();
while (!executor.isTerminated()) {
}
ExecutorService executor2 = Executors.newFixedThreadPool(5);
for (int i = 0; i < 10; i++) {
Runnable worker = new AnotherTask("" + i);
executor2.execute(worker);
}
executor2.shutdown();