有一个带有单个线程的线程池,用于执行多个线程提交的任务。该任务实际上由两部分组成 - perform
具有有意义的结果,cleanup
需要相当长的时间,但不会返回有意义的结果。目前(显然不正确)实现看起来像这样。是否有一种优雅的方法可以确保仅在之前的perform
任务之后执行另一个cleanup
任务?
public class Main {
private static class Worker {
int perform() {
return 1;
}
void cleanup() {
}
}
private static void perform() throws InterruptedException, ExecutionException {
ExecutorService pool = Executors.newFixedThreadPool(1);
Worker w = new Worker();
Future f = pool.submit(() -> w.perform());
pool.submit(w::cleanup);
int x = (int) f.get();
System.out.println(x);
}
}
答案 0 :(得分:1)
如果您使用的是java8,则可以使用CompletableFuture
CompletableFuture.supplyAsync(() -> w.perform(), pool)
.thenApplyAsync(() -> w.cleanup(), pool)
.join();
答案 1 :(得分:1)
是否有一种优雅的方法可以确保只有在之前的清理任务之后才能执行另一个执行任务?
最明显的做法是从cleanup()
拨打perform()
,但我认为你有理由不这样做。
你说你的解决方案目前正在"显然不正确"。为什么?因为竞争条件?然后你可以添加一个synchronized
块:
synchronized (pool) {
Future f = pool.submit(() -> w.perform());
pool.submit(w::cleanup);
}
这样可以确保cleanup()
在perform()
之后立即出现。如果您担心synchronized
的性能受到影响,请不要。
另一个解决方案可能是使用ExecutorCompletionService
class,但我不确定这对一个线程有何帮助。我之前在另一个线程池中运行清理任务时使用过它。