java - 多线程程序永远不会停止执行
问题描述
我有一个多线程快速排序算法,女巫运行正确,但永远不会停止执行。
我尝试在任何地方添加返回声明,但没有任何帮助。
完成后如何阻止所有线程运行?有没有办法让线程在完成后终止其自身?
public class Parallel {
private static final int numberOfThreads = Runtime.getRuntime().availableProcessors();
private static final int fallback = 2;
private static Executor pool = Executors.newFixedThreadPool(numberOfThreads);
//public static int[] numberArray;
public static <T extends Comparable<T>> void sort(int[] numberArray){
if(numberArray == null || numberArray.length == 0){
return;
}
final AtomicInteger count = new AtomicInteger(1);
pool.execute(new QuicksortRunnable<T>(numberArray, 0, numberArray.length-1, count));
try {
synchronized (count) {
count.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private static class QuicksortRunnable<T extends Comparable<T>> implements Runnable {
private final int[] values;
private final int left;
private final int right;
private final AtomicInteger count;
public QuicksortRunnable(int[] values, int left, int right, AtomicInteger count) {
this.values = values;
this.left = left;
this.right = right;
this.count = count;
}
@Override
public void run() {
quicksort(left, right);
synchronized (count) {
// AtomicInteger.getAndDecrement() returns the old value. If the old value is 1, then we know that the actual value is 0.
if (count.getAndDecrement() == 1)
count.notify();
}
return;
}
private void quicksort(int pLeft, int pRight) {
int pivotIndex = (pRight - pLeft) / 2 + pLeft;
int pivot = values[pivotIndex];
int j = pRight;
int i = pLeft;
while (i < j) {
while (values[i] > pivot) {
i++;
}
while (values[j] < pivot) {
j--;
}
if (i <= j) {
int temp = values[i];
values[i] = values[j];
values[j] = temp;
i++;
j--;
}
}
if (count.get() >= fallback * numberOfThreads) {
if (pLeft < j){
quicksort(pLeft, j);
}
if (i < pRight) {
quicksort(i, pRight);
}
} else {
if (pLeft < j) {
count.getAndAdd(1);
pool.execute(new QuicksortRunnable<T>(values, pLeft, j, count));
}
if (i < pRight) {
count.getAndAdd(1);
pool.execute(new QuicksortRunnable<T>(values, i, pRight, count));
}
}
}
}
还有我的主要功能
public static void main(String args[]) {
Random rand = new Random();
int length = 100000;
int[] parallelArray = new int[length];
for (int i = 0; i < length; i++) {
int temp = rand.nextInt(length);
parallelArray[i] = temp;
}
sort(parallelArray);
boolean t = check(parallelArray);
System.out.println(t);
}
测试代码是否排序的函数。
public static boolean check(int[] A) {
for (int i = 0; i < A.length - 1; i++) {
// System.out.print(" " + A[i]);
if (A[i] < A[i + 1]) {
return false;
}
}
return true;
}
解决方案
当您使用 a 时,ExecutorService
您需要ExecutorService.shutdown()
在所有任务提交后调用,然后您需要通过调用等待池关闭ExecutorService.awaitTermination()
并提供等待时间作为参数。这是因为池由非守护线程组成,如果非守护线程仍在运行,jvm 不会退出。
因此,将 this 更改为使用ExecutorService
fromExecutor
来启用挂钩:
private static ExecutorService pool = Executors.newFixedThreadPool(numberOfThreads);
然后shutdown()
在finally
块中调用:
public static <T extends Comparable<T>> void sort(int[] numberArray) {
if (numberArray == null || numberArray.length == 0) {
return;
}
final AtomicInteger count = new AtomicInteger(1);
pool.execute(new QuicksortRunnable<T>(numberArray, 0, numberArray.length - 1, count));
try {
synchronized (count) {
count.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
pool.shutdown(); //call shutdown() here
try {
pool.awaitTermination(5, TimeUnit.MINUTES); //wait for 5 minutes
}catch (InterruptedException ie) {
ie.printStackTrace();
}
}
}
在finally
调用部分调用shutdown()
以启动池中线程的有序关闭,并且由于shutdown
调用没有阻塞,awaitTermination()
因此必须调用调用线程以等待关闭过程完成。
5分钟等待是不是有点太多了?
调用awaitTermination
不一定要等待整整五分钟。5 分钟是等待的最长时间,而不是最短时间。对于 Javadoc:
阻塞直到所有任务在关闭请求后完成执行,或者发生超时,或者当前线程被中断,以先发生者为准。
推荐阅读
- webpack - 将 Sass 与 Vue-loader webpack 堆栈正确集成
- html - CSS页脚网格响应
- angularjs - AngularJS $http.post 不向 Django REST 后端发送数据
- java - 重启后Hbase数据被删除
- azure-sql-database - 无法导出 Azure SQL 数据库
- r - 直方图中的条数 - R
- python - 从另一个字典中删除重复值
- javascript - Javascript - 我应该如何从两个引号之间获取值?
- javascript - 最小步数
- javascript - Ionic 3 - 如果同时激活(JS)