5

我正在实施并行快速排序作为编程实践,完成后,我阅读了 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() 相同的功能,但使用 Executor,我的问题是:

这是等待所有线程完成的最佳方法吗?

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

4

4 回答 4

9

您使用的是什么类型的执行器?

ThreadPoolExecutor.awaitTermination()会做你所问的(它实际上是一个批量连接操作)。

总的来说,ThreadPoolExecutor 将允许您对线程数等设置限制...(如果线程数变高,不确定,可能比递归更好)。

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

于 2009-11-24T03:49:21.833 回答
4

看看Executors.newFixedThreadPool哪个可以让您创建最多 n 个线程的池(摆脱您的“if”)以及ExecutorService.shutdown方法和ExecutorsService.awaitTermination方法。

于 2009-11-24T03:50:54.480 回答
2

你可以使用CountDownLatch

于 2009-11-24T09:37:29.170 回答
1

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

这是不正确的。

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

您需要正确调用工厂类。

此外,您还需要决定一个策略来处理作业提交到队列的速度快于它们被消耗的情况,因为您最初可能不会由于线程执行的限制而耗尽内存,但是如果您排队数百万作业,那么它们必须在等待执行时存储在某个地方。

于 2012-07-05T13:12:09.933 回答