2009-11-24 94 views
5

我正在实现parellel quicksort作为编程实践,并且在完成后,我阅读了Executors上的Java教程页面,这听起来像可以让我的代码更快。不幸的是,我依靠join()来确保程序不会继续,直到所有内容都被排序为止。现在,我使用:等待Executor中的所有线程完成?

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); 
    } 
} 

这似乎是工作正常,但如果我跑e.shutdown()我叫之后我的非递归快速()方法,它有一堆RejectedExecutionExceptions的,所以我认为这不像我想要的那样好。

所以无论如何,我基本上试图让相同的功能leftThread.join(),但与执行者,而我的问题是:

这是要等到所有线程的最佳途径完成?

编辑:好的,所以我想出了为什么我关闭了我的执行程序后出现了一堆错误,这是因为我在循环中调用了这个函数(以平衡运行时间)而不是创建新的执行程序。

回答

9

你正在使用什么类型的执行器?

ThreadPoolExecutor.awaitTermination()会做你在问什么(这实际上是一个批量连接操作)。作为一个总的来说,ThreadPoolExecutor将允许你设置对线程数量的限制,等等......(如果线程数量变高,不确定的话,可能比你要做的递归更好)。

PS - 我怀疑执行程序会让你的代码更快运行,但它们可能会让你的代码更易于阅读和维护。使用线程池可以使这类算法变得更快,而Executor可以很容易地处理线程池。

+1

如果您不希望1000个线程拥塞您的网络接口,ThreadPoolExecutors非常适合下载图像。顺便说一句,我很确定Android使用Executors在后台管理他们的ASyncTasks。 – manmal 2012-01-23 10:18:57

1

PS - 我怀疑遗嘱执行人将会使你的代码运行得更快,但 他们可能使你的代码更容易阅读和维护。使用线程 池可以使这种算法变得更快,Executor使得使用线程池更容易。

这是不正确的。

执行程序可以由任何数量的不同执行系统“支持”,包括池化线程。

您需要正确调用工厂类。

此外,你还需要一个政策决定,涉及以作业提交到队列的速度比他们可以食用的情况下,因为你可能最初耗尽内存由于对线程执行的限制,但是如果你排列了数百万个工作,那么他们在等待执行时必须存放在某个地方。