java 等待 Executor 中的所有线程完成?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1787602/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Wait for all threads in an Executor to finish?
提问by Brendan Long
I'm implementing a parellel quicksort as programming practice, and after I finished, I read the Java tutorial page on Executors, which sound like they could make my code even faster. Unfortunately, I was relying on join()'s to make sure that the program doesn't continue until everything is sorted. Right now I'm using:
我正在实施并行快速排序作为编程实践,完成后,我阅读了 Executors 上的 Java 教程页面,听起来它们可以使我的代码更快。不幸的是,我依靠 join() 来确保程序在所有内容都被排序之前不会继续。现在我正在使用:
public static void quicksort(double[] a, int left, int right) {
if (right <= left) return;
int i = partition(a, left, right);
// threads is an AtomicInteger I'm using to make sure I don't
// spawn a billion threads.
if(threads.get() < 5){
// ThreadSort's run method just calls quicksort()
Future leftThread = e.submit(new ThreadSort(a, left, i-1));
Future rightThread = e.submit(new ThreadSort(a, i+1, right));
threads.getAndAdd(2);
try {
leftThread.get();
rightThread.get();
}
catch (InterruptedException ex) {}
catch (ExecutionException ex) {}
}
else{
quicksort(a, left, i-1);
quicksort(a, i+1, right);
}
}
This seems to work ok, but if I run e.shutdown() right after I call my non-recursive quicksort() method, it has a bunch of RejectedExecutionExceptions, so I assume this isn't working as well as I had wanted.
So anyway, I'm basically trying to get the same functionality as leftThread.join() but with an Executor, and my questions is:
Is this the best way to wait until all of the threads are done?
EDIT: Ok, so I figured out why I got a bunch of errors after shutting down my Executor, it was because I was calling this function in a loop (to even out run times) and not creating a new Executor.
这似乎工作正常,但如果我在调用我的非递归 quicksort() 方法后立即运行 e.shutdown(),它有一堆 RejectedExecutionExceptions,所以我认为这不像我想要的那样工作。
所以无论如何,我基本上是想获得与 leftThread.join() 相同的功能,但有一个 Executor,我的问题是:
这是等待所有线程完成的最佳方法吗?
编辑:好的,所以我想出了为什么在关闭我的 Executor 后我会收到一堆错误,这是因为我在循环中调用这个函数(以平衡运行时间)而不是创建一个新的 Executor。
回答by Kevin Day
What type of executor are you using?
你使用什么类型的执行器?
ThreadPoolExecutor.awaitTermination()will do what you are asking about (it's effectively a bulk join operation).
ThreadPoolExecutor.awaitTermination()会做你所问的(它实际上是一个批量连接操作)。
As a total aside, ThreadPoolExecutor will allow you to set limits on the # of threads, etc... (might be better than going recursive like what you are doing if the thread count goes high, not sure).
总而言之,ThreadPoolExecutor 将允许您对线程数等设置限制......(如果线程数变高,则可能比递归更好,不确定)。
PS - I doubt that executors will make your code run any faster, but they may make your code easier to read and maintain. Using a Thread pool will make things faster for this sort of algorithm, and the Executor makes it easy to work with thread pools.
PS - 我怀疑执行程序会让您的代码运行得更快,但它们可能会使您的代码更易于阅读和维护。使用线程池将使这种算法的速度更快,并且执行器可以轻松地使用线程池。
回答by TofuBeer
Take a look at Executors.newFixedThreadPoolwhich lets you create a pool of at most n threads (gets rid of your "if") and the ExecutorService.shutdownmethod and the ExecutorsService.awaitTerminationmethod.
看看Executors.newFixedThreadPool它可以让您创建一个最多包含 n 个线程的池(摆脱您的“if”)以及ExecutorService.shutdown方法和ExecutorsService.awaitTermination方法。
回答by crowne
You could use a CountDownLatch
你可以使用CountDownLatch
回答by bob
PS - I doubt that executors will make your code run any faster, but they may make your code easier to read and maintain. Using a Thread pool will make things faster for this sort of algorithm, and the Executor makes it easy to work with thread pools.
PS - 我怀疑执行程序会让您的代码运行得更快,但它们可能会使您的代码更易于阅读和维护。使用线程池将使这种算法的速度更快,并且执行器可以轻松地使用线程池。
This is not correct.
这是不正确的。
The executor can be 'backed' by any number of different execution systems including pooled threads.
执行器可以由任意数量的不同执行系统(包括池线程)“支持”。
You need to call the factory class correctly.
您需要正确调用工厂类。
Furthermore you also need to decide on a policy for dealing with situations where jobs are submitted to the queue faster than they can be consumed, because you may notinitially run out of memory due to limits on the thread execution, but if you queue millions of jobs, then they have to be stored some place whilst they wait for execution.
此外,您还需要决定一个策略来处理作业提交到队列的速度比它们可以消耗的速度快的情况,因为您最初可能不会因为线程执行的限制而耗尽内存,但是如果您将数百万作业,那么它们必须在等待执行时存储在某个地方。

