代码之家  ›  专栏  ›  技术社区  ›  Brendan Long

等待执行器中的所有线程完成?

  •  5
  • Brendan Long  · 技术社区  · 15 年前

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

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

    编辑:好的,所以我知道了为什么在关闭执行器之后出现了很多错误,这是因为我在一个循环中调用了这个函数(以平衡运行时间),而没有创建一个新的执行器。

    4 回复  |  直到 12 年前
        1
  •  9
  •   bluish dmajkic    13 年前

    您使用的是哪种类型的执行器?

    ThreadPoolExecutor .awaitTermination() 将执行您所要求的操作(实际上是批量加入操作)。

    总而言之,threadpoolexecutor允许您对线程等设置限制…(如果线程数变大,可能比像进行递归要好,不确定)。

    我怀疑执行器会让你的代码运行得更快,但是它们会让你的代码更容易阅读和维护。使用线程池将使这种算法更快,而执行器使线程池更容易使用。

        2
  •  4
  •   bluish dmajkic    13 年前

    看一看 Executors.newFixedThreadPool 它允许您创建最多n个线程的池(去掉“if”)和 ExecutorService.shutdown 方法和 ExecutorsService.awaitTermination 方法。

        3
  •  2
  •   crowne    15 年前

    你可以用一个 CountDownLatch

        4
  •  1
  •   bob    12 年前

    我怀疑执行器会让你的代码运行得更快,但是 它们可能使您的代码更易于阅读和维护。使用线程 池将使这种算法更快,并且 执行器使处理线程池变得容易。

    这是不正确的。

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

    你需要正确地调用工厂类。

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