线程池有个疑问,我的机器 4 核 16G,按照最优的线程数 2n+1 来说为 9 个,但是在如下代码中
public static void main(String[] args) {
// 创建线程池,500 个线程数
ExecutorService es = ThreadUtils.getInstance("approveProcessForBatch", 500);
Map<Integer, Future<Object>> futureMap = new HashMap<>(SystemConstant.INITIAL_CAPACITY);
for (int i = 0; i <= 250; i++) {
// delay5s 耗时 5s
es.submit(() -> delay5s(""));
}
System.out.println("开始执行时间:" + DateTime.now());
for (int i = 0; i <= 100; i++) {
int finalI = i;
Future<Object> future = es.submit(() -> delay5s("当前任务" + finalI));
futureMap.put(finalI, future);
}
futureMap.keySet().forEach(i -> {
try {
// v 是当前任务名称
Object v = futureMap.get(i).get();
System.out.println(v + ",完成时间:" + DateTime.now());
} catch (ExecutionException | InterruptedException e) {
throw new BusinessException(e);
}
});
}
目前设置了 500 个线程数,会在 5s 之后将 100 个任务全部完成,假如我只设置 9 个,那预计需要 250/9 * 5s 的时间,导致这个现象的原因是啥?
1
blankmiss 2023-05-15 15:41:30 +08:00
什么原因 你倒是说清楚啊
|
2
mango88 2023-05-15 16:02:57 +08:00
从你的描述看,ThreadUtils.getInstance 代码仅是设置了 corePoolSize
不清楚你的这段代码是如何设置线程池其他几个参数的,maximumPoolSize ,workQueue 等 如果是无界队列的话,队列满了才会去创建新的线程(线程数 > corePoolSize )直到线程数 = maximumPoolSize |
3
misdake 2023-05-15 16:04:14 +08:00
delay5s 的实现能给么,你说“delay5s 耗时 5s”,是不是线程 sleep 而不是一直占用 cpu 。
|
5
hanstyle 2023-05-15 16:09:51 +08:00
可能要看下 delay5s()方法是不是没占用 cpu 资源
|
6
vagusss 2023-05-15 16:30:10 +08:00
线程数的设置主要还是看任务类型, cpu 密集型和其他类型比如 IO 密集型不能一概而论
|
7
vagusss 2023-05-15 16:31:50 +08:00
google 一下有很多文章讲解, 我随便搜了一篇 https://juejin.cn/post/7072281409053786120
|
8
notwaste 2023-05-15 16:40:34 +08:00
delay5s 如果是 Thread.sleep 的话会释放 CPU ,在一个线程 delay5s 的同时 CPU 会去执行其他线程的 delay5s
|
9
oldshensheep 2023-05-15 17:40:33 +08:00
因为你线程都在 sleep ,啥都没干。
不过 Java 的 Virtual Thread 正式在 JDK21 发布,就基本上没什么线程池的事了 |
10
kirito41dd 2023-05-15 19:18:04 +08:00
@oldshensheep java8: 你说啥?(
|
11
opengps 2023-05-15 23:35:45 +08:00 via Android
线程的动态创建就是这么慢,一秒才一个
|
12
WashFreshFresh 2023-05-16 10:04:35 +08:00
如果线程池是无界队列,coresize 和 maxsize 都是你给的线程数的话,就解释的通。每次都只能提交 9 个任务,然后卡住了,等 5s 后任务结束,线程都释放了,才能继续提交新的任务。
|
13
wholve OP delay5s 这个方法我自定义的,模拟业务方法耗时,我直接 sleep 了 5s 确实没有占用 cpu;
真实的业务方法,包含查询 sql,调用外部接口,以及业务代码,估计也是没有一直占用 cpu 资源导致的吧? |