Threaded quick release device

Hello I have never tried using streams before, this is my first attempt, but it does not stop. Normal mode works. if I remove the awaitTermination it looks like it works, but I need this method to end when it has parsed everything (a pun intended for XD). Can you tell me what I did wrong? Thank.

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


source to share


3 answers


Instead of waiting for the entire executor service to complete (which is probably not what you want at all), you should keep everything Future

returned executor.submit()

and wait until they are all done (by calling 'get () `on them. eg).

And while it makes you think about it in the method qsortParallelo()

, which will actually lead to a deadlock due to exhaustion of the thread pool: parent tasks will depend on worker threads waiting for their child tasks to finish, but child tasks will never be scheduled because they are not there will be worker threads available.

So, first you have to collect all objects Future

into a parallel collection, return the result in qsortP()

and wait for completion Future

.

Or use ForkJoinPool

one that has been designed for exactly this kind of task, and does the whole ass for you. Recursively transferring tasks to the executor from the application code is usually not a good idea, it is very easy to understand that this is wrong.




As an aside, the reason your code is deadlocked is because every worker thread gets stuck in executor.awaitTermination()

, thus preventing the executor from terminating.

In general, the two most useful tools for designing and debugging multithreaded applications are:

  • Stream dump. You can generate this with jstack

    VisualVM or any other tool, but it is invaluable in deadlock situations, it gives an accurate image of not continuing with your themes.
  • A pen, a piece of paper and a drawing of a nice old-fashioned floating chart.
+1


source


You call executor.awaitTermination

inside Thread

, which was started by yours executor

. Thread

does not stop until executor

it exits awaitTermination

and executor

exits awaitTermination

until it ends Thread

. You need to move this code:

try {
  executor.awaitTermination(1, TimeUnit.DAYS);
} catch (InterruptedException e) {
  e.printStackTrace();
}

      



at the end of the method qsortP

.

+1


source


The error in this code is just a while loop in qsortParallelo

. first

and last

never change. Also, you don't need a while loop, as you are already doing this further sorting in the executor. And you need to run a second task on the second half of the array.

0


source







All Articles