等待Executor中的所有线程完成?
我正在实现一个parellel quicksort作为编程实践,在我完成之后,我阅读了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); } }
这似乎工作正常,但如果我在调用我的非递归quicksort()方法后立即运行e.shutdown(),它有一堆RejectedExecutionExceptions,所以我认为这不像我想要的那样好。
所以无论如何,我基本上试图获得与leftThread.join()相同的function但是使用Executor,我的问题是:
这是等待所有线程完成的最佳方式吗?
编辑:好的,所以我弄清楚为什么在关闭我的Executor后出现了一堆错误,这是因为我在一个循环中调用了这个函数(甚至运行时间)并且没有创建一个新的Executor。
你使用什么类型的执行者?
ThreadPoolExecutor
.awaitTermination()
将执行您所要求的(它实际上是批量连接操作)。
总而言之,ThreadPoolExecutor允许你设置线程数等的限制……(如果线程数很高,可能比你正在做的递归更好,不确定)。
PS – 我怀疑执行程序会让你的代码运行得更快,但它们可能使你的代码更容易阅读和维护。 使用线程池可以使这种算法更快,Executor使得使用线程池变得更容易。
看一下Executors.newFixedThreadPool
,它允许你创建一个最多n个线程的池(删除你的“if”)和ExecutorService.shutdown
方法以及ExecutorsService.awaitTermination
方法。
您可以使用CountDownLatch
PS – 我怀疑执行程序会让你的代码运行得更快,但它们可能使你的代码更容易阅读和维护。 使用线程池可以使这种算法更快,Executor使得使用线程池变得更容易。
这是不正确的。
执行程序可以由任意数量的不同执行系统“支持”,包括池化线程。
您需要正确调用工厂类。
此外,您还需要确定一个策略来处理将作业提交到队列的速度比使用它们的速度更快的情况,因为由于线程执行的限制,您最初可能不会耗尽内存,但如果排队数百万工作,然后他们必须在等待执行时存储在某个地方。