java - 线程池无法创建本机线程
问题描述
我正在尝试以各种方式实现合并排序。我确实用它实现了它fork/join
,现在我想用它来实现它ExecutorService
and Threadpool
。
我目前的工作如下:
public class Test<T> implements Comparable<T> {
private final ThreadPoolExecutor executor;
public Test() {
//having this kind of threadpool prevent the program from generating any output whatsoever.
//executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
executor = (ThreadPoolExecutor) Executors.newCachedThreadPool();
}
private void divide(LinkedList<T> dataToBeSorted) {
if (dataToBeSorted.size() < 2) {
return;
}
int mid = dataToBeSorted.size() / 2;
LinkedList<T> left = new LinkedList<>(dataToBeSorted.subList(0, mid));
LinkedList<T> right = new LinkedList<>(dataToBeSorted.subList(mid, dataToBeSorted.size()));
Future<?> f1= (executor.submit(() -> divide(left)));
Future<?> f2= (executor.submit(() -> divide(right)));
try {
f1.get();
f2.get();
} catch (InterruptedException | ExecutionException e) {
System.out.println("something went wrong went to sequential merge sort!");
new SeqMergeSorter<T>().sort(dataToBeSorted);
return;
}
merge(left, right, dataToBeSorted);
}
public static<T> void sort(LinkedList<T> dataToBeSorted){
if (dataToBeSorted.size() < 2)
return;
var temp=new Test<T>();
temp.divide(dataToBeSorted);
temp.executor.shutdownNow();
}
编辑部分:
上面的代码已经更新。
我添加了
future
并尝试以单独的方法将其关闭。现在我得到一个排序的元素,但只要我的设备可以产生线程。由于产生无限线程并在我得到以下输出
newCachedThreadPool
后取消它们:60s
[1.427s][warning][os,thread] Failed to start thread - pthread_create failed (EAGAIN) for attributes: stacksize: 1024k, guardsize: 0k, detached.
更改为时
newCachedThreadPool
,newFixedThreadPool(Runtime.getRuntime().availableProcessors())
我将没有任何输出!
解决方案
您的解决方案是多线程并创建大量中间数据结构,请理解它很可能比更优化的单线程实现慢得多。特别是最终访问的是内存,并且由于合并排序的处理方式,事情会随处移动。基本上,除非比较成本巨大,否则该算法将受到主内存性能/缓存而不是 CPU 的限制。
但是从技术上讲,您的实现不是线程安全的,并且不等待子任务完成。
因此,通常 var left 和 right 稍后可能会由另一个线程排序,但会立即合并而不等待单个排序结果。
您需要合并等待左和右首先被排序,然后才合并结果。
如果您不等待,将在非线程安全数据结构上同时执行,并且程序将出现错误行为。
推荐阅读
- python - 如何为具有扩展用户(onetoone 字段)关系的模型执行 put/patch 方法 django rest框架
- jquery - 从 ajax 调用传回的数据中选择特定项目
- sql - 简化 Oracle 中的现有查询
- c# - 在我给它一个输入之后,我的程序一直跳到 else 语句。我已经尝试了一些东西,但没有任何工作。(C#)
- android - 如何使用另一个外部xml视图android?
- woocommerce - 如何获取 Wocomerce 根 URL 以显示商店?
- java - 未能执行目标 org.apache.maven.plugins:maven-gpg-plugin:1.5:sign
- java - 如何在不级联删除 ChildEntities 的情况下删除(@ManyToOne)实体?
- python - matplotlib 将 df 绘制到矩形
- reactjs - 我的 React 应用程序在我的 PC 上无法正常工作