[英]Threaded quicksort
Hello I've never tried using threads before, this is my first attempt but it doesn't stop, The normal verion works. 您好我以前从未尝试过使用过线程,这是我的第一次尝试,但它并没有停止,正常的版本有效。 if I remove awaitTermination it looks like it works but I need the method to finish when it's all sorted out(pun intended XD).
如果我删除awaitTermination它看起来像它的工作但我需要该方法完成它全部整理(双关语意图XD)。 Can you tell me what I did wrong?
你能告诉我我做错了什么吗? Thank you.
谢谢。
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);
}
}
}
You are calling executor.awaitTermination
inside a Thread
which was launched by your executor
. 您在
executor.awaitTermination
启动的Thread
中调用executor
。 Thread
will not stop until executor
comes out of the awaitTermination
and executor
will not come out of awaitTermination
until the Thread
terminates. Thread
不会停止,直到executor
退出awaitTermination
并且executor
将不会退出awaitTermination
直到Thread
终止。 You need to move this code: 您需要移动此代码:
try {
executor.awaitTermination(1, TimeUnit.DAYS);
} catch (InterruptedException e) {
e.printStackTrace();
}
into the end of qsortP
method. 进入
qsortP
方法的最后。
Instead of waiting for termination of the entire executor service (which probably isn't what you want at all), you should save all the Future
s returned by executor.submit()
and wait until they're all done (by calling 'get()` on them for example). 你应该保存
executor.submit()
返回的所有Future
,而不是等待终止整个执行程序服务(可能根本不是你想要的),并等到它们全部完成(通过调用'get ()`例如,他们)。
And though it's tempting to do this in the qsortParallelo()
method, that would actually lead to a deadlock by exhaustion of the thread pool: parent tasks would hog the worker threads waiting for their child tasks to complete, but the child tasks would never be scheduled to run because there would be no available worker threads. 尽管在
qsortParallelo()
方法中这样做很有吸引力,但这实际上会导致线程池耗尽导致死锁:父任务会占用工作线程等待子任务完成,但子任务永远不会计划运行,因为没有可用的工作线程。
So you have to collect all the Future
objects into a concurrent collection first, return the result to qsortP()
and wait there for the Future
s to finish. 因此,您必须首先将所有
Future
对象收集到并发集合中,将结果返回到qsortP()
并等待Future
s完成。
Or use a ForkJoinPool
, which was designed for exactly this kind of task and does all the donkey work for you. 或者使用
ForkJoinPool
,它专为完成此类任务而设计,并为所有驴工作。 Recursively submitting tasks to an executor from application code is generally not a very good idea, it's very easy to get it wrong. 从应用程序代码递归地向执行程序提交任务通常不是一个好主意,它很容易弄错。
As an aside, the reason your code is deadlocked as it is is that every worker thread is stuck in executor.awaitTermination()
, thereby preventing the termination of the executor service. 顺便说一下,你的代码死锁的原因是每个工作线程都停留在
executor.awaitTermination()
,从而阻止了执行程序服务的终止。
In general, the two most useful tools for designing and debugging multi-threaded applications are: 通常,设计和调试多线程应用程序的两个最有用的工具是:
jstack
, VisualVM or any other tool, but it's invaluable in deadlock situations, it gives you an accurate image of what's (not) going on with your threads. jstack
,VisualVM或任何其他工具生成它,但它在死锁情况下非常有用,它可以准确地显示线程中(不)的内容。 The mistake in this code is simply the while-loop in qsortParallelo
. 这段代码中的错误只是
qsortParallelo
的while循环。 first
and last
are never modified. 从不修改
first
和last
。 Apart from that you don't need the while-loop, since you already do that the further sorting in the executor. 除此之外,您不需要while循环,因为您已经在执行程序中进行了进一步排序。 And you'll need to start another task for the second half of the array.
而且你需要为数组的后半部分启动另一个任务。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.