Java在主线程上等待一批工作完成时重用FixedThreadPool

时间:2018-02-07 13:21:25

标签: java multithreading parallel-processing

我是Java多线程的新手,我发现了一些responses用于我正在尝试做的事情。然而,作为java线程的新手,我仍然很难跟踪响应。

基本上这就是我所拥有的:

private final ExecutorService mFixedThreadPool;

public ThreadPool(int threadCount) {
    mFixedThreadPool = Executors.newFixedThreadPool(threadCount);
}

public interface Task {
    void phase1();
    void phase2();
    void phase3();
}

public void executeBatch(List<Runnable> tasks) {
    tasks.forEach(task -> mFixedThreadPool.execute(task::phase1));
    tasks.forEach(task -> mFixedThreadPool.execute(task::phase2));
    tasks.forEach(task -> mFixedThreadPool.execute(task::phase3));
    //only return on the main thread once all the tasks are complete.
    //(Dont destroy threadpool as the "executeBatch" method will be called in a loop)
}

我想暂停或停止或等待调用“executeBatch”的线程,直到批量工作完成。我知道可以使用mFixedThreadPool.shutdown()然后等待它成功关闭,但是我想经常多次重复使用这些线程,所以每次关闭效率都很低。

2 个答案:

答案 0 :(得分:1)

如果你想要的是一个没有启动下一个线程的线程池,直到前一个线程完成,你可以简单地用一个线程创建一个FixedThreadPool:

ExecutorService threadPool = Executors.newFixedThreadPool(1);

如果您想要的是睡眠当前线程,直到池完成使用关闭。 shutdown()正是为了这种任务,但在关机后你需要创建一个新的ExecutorService:

threadPool.shutdown();
try {
  threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
} catch (InterruptedException e) {
  ...
}

您可以将ExecutorService封装在ExecutorCompletionService中。这将在完成时通知您,而不会像您想要的那样关闭Executor。查看一些信息here

最后一个选择是使用Future。 get()方法阻塞,直到该线程完成,因此您可以:

ExecutorService threadPool = Executors.newFixedThreadPool(4);
List<Callable<String>> tasks = new ArrayList<>();
List<Future<String>> futures = new ArrayList<>();
List<String> result = new ArrayList<>();
tasks.stream().forEachOrdered(task -> futures.add(threadPool.submit(task)));
for (Future<String> future :futures) {
    try {
        result.add(future.get());
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (ExecutionException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }   
}

答案 1 :(得分:0)

我认为fork/join framework可以为您提供所需内容。 您可以控制执行,如果需要,可以执行unfork任务并在主线程中计算它。