螺纹快速排序

时间:2015-04-22 19:02:41

标签: java multithreading quicksort executorservice

您好我以前从未尝试使用过线程,这是我的第一次尝试,但它没有停止,正常的版本有效。 如果我删除awaitTermination它看起来像它的工作但我需要该方法完成它全部整理(双关语意图XD)。 你能告诉我我做错了什么吗? 谢谢。

public class Sorting {

  private Sorting() {};

  private static Random r = new Random();
  private static int cores = Runtime.getRuntime().availableProcessors();
  private static ExecutorService executor = Executors.newFixedThreadPool(cores);

  public static void qsortP(int[] a) {
    qsortParallelo(a, 0, a.length - 1);
  }

  private static void qsortParallelo(int[] a, int first, int last) {
    while (first < last) {
      int p = first + r.nextInt(last - first + 1);
      int px = a[p];
      int i = first, j = last;
      do {
        while (a[i] < px)
          i++;
        while (a[j] > px)
          j--;
        if (i <= j) {
          scambia(a, i++, j--);
        }
      } while (i <= j);
      executor.submit(new qsortThread(a, first, j));
      first = i;
    }
    try {
      executor.awaitTermination(1, TimeUnit.DAYS);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }

  private static void scambia(int[] a, int x, int y) {
    int temp = a[x];
    a[x] = a[y];
    a[y] = temp;
  }

  public static class qsortThread implements Runnable {
    final int a[], first, last;

    public qsortThread(int[] a, int first, int last) {
      this.a = a;
      this.first = first;
      this.last = last;
    }

    public void run() {
      qsortParallelo(a, first, last);
    }
  }
}

3 个答案:

答案 0 :(得分:1)

您正在executor.awaitTermination内的Thread内拨打executorThread executor awaitTermination executor awaitTermination Thread try { executor.awaitTermination(1, TimeUnit.DAYS); } catch (InterruptedException e) { e.printStackTrace(); } qsortP {{1}} {{1}} {{}}} {{1}} {{}}} {{}}}您需要移动此代码:

{{1}}

到{{1}}方法的末尾。

答案 1 :(得分:1)

您应该保存Future返回的所有executor.submit(),而不是等待终止整个执行程序服务(可能根本不是您想要的服务),而是等到它们和#39;全部完成(例如,通过调用&#39; get()`)。

尽管在qsortParallelo()方法中这样做很有吸引力,但这实际上会因线程池耗尽而导致死锁:父任务会占用等待子任务的工作线程完成,但子任务永远不会被安排运行,因为没有可用的工作线程。

因此,您必须先将所有Future个对象收集到并发集合中,然后将结果返回到qsortP()并等待Future完成。

或者使用专为此类任务而设计的ForkJoinPool,并为所有驴工作。从应用程序代码递归地向执行程序提交任务通常不是一个好主意,它很容易弄错。

顺便说一下,你的代码死锁的原因是每个工作线程都卡在executor.awaitTermination()中,从而阻止了执行程序服务的终止。

通常,设计和调试多线程应用程序的两个最有用的工具是:

  1. 线程转储。您可以使用jstack,VisualVM或任何其他工具生成它,但它在死锁情况下非常有用,它可以准确地显示您的线程发生了什么(不)。< / LI>
  2. 一支笔,一张纸,画出一张旧式的泳道图。

答案 2 :(得分:0)

此代码中的错误只是qsortParallelo中的while循环。永远不会修改firstlast。除此之外,你不需要while循环,因为你已经在执行程序中进行了进一步的排序。而且你需要为阵列的后半部分开始另一项任务。