关于线程池的问题

2023-05-15 15:11:36 +08:00
 wholve

线程池有个疑问,我的机器 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 的时间,导致这个现象的原因是啥?

1822 次点击
所在节点    程序员
13 条回复
blankmiss
2023-05-15 15:41:30 +08:00
什么原因 你倒是说清楚啊
mango88
2023-05-15 16:02:57 +08:00
从你的描述看,ThreadUtils.getInstance 代码仅是设置了 corePoolSize
不清楚你的这段代码是如何设置线程池其他几个参数的,maximumPoolSize ,workQueue 等
如果是无界队列的话,队列满了才会去创建新的线程(线程数 > corePoolSize )直到线程数 = maximumPoolSize
misdake
2023-05-15 16:04:14 +08:00
delay5s 的实现能给么,你说“delay5s 耗时 5s”,是不是线程 sleep 而不是一直占用 cpu 。
mango88
2023-05-15 16:05:10 +08:00
@mango88 更正一下,如果是无界队列的话, => ~如果是无界队列的话,~
hanstyle
2023-05-15 16:09:51 +08:00
可能要看下 delay5s()方法是不是没占用 cpu 资源
vagusss
2023-05-15 16:30:10 +08:00
线程数的设置主要还是看任务类型, cpu 密集型和其他类型比如 IO 密集型不能一概而论
vagusss
2023-05-15 16:31:50 +08:00
google 一下有很多文章讲解, 我随便搜了一篇 https://juejin.cn/post/7072281409053786120
notwaste
2023-05-15 16:40:34 +08:00
delay5s 如果是 Thread.sleep 的话会释放 CPU ,在一个线程 delay5s 的同时 CPU 会去执行其他线程的 delay5s
oldshensheep
2023-05-15 17:40:33 +08:00
因为你线程都在 sleep ,啥都没干。
不过 Java 的 Virtual Thread 正式在 JDK21 发布,就基本上没什么线程池的事了
kirito41dd
2023-05-15 19:18:04 +08:00
@oldshensheep java8: 你说啥?(
opengps
2023-05-15 23:35:45 +08:00
线程的动态创建就是这么慢,一秒才一个
WashFreshFresh
2023-05-16 10:04:35 +08:00
如果线程池是无界队列,coresize 和 maxsize 都是你给的线程数的话,就解释的通。每次都只能提交 9 个任务,然后卡住了,等 5s 后任务结束,线程都释放了,才能继续提交新的任务。
wholve
2023-05-17 18:12:06 +08:00
delay5s 这个方法我自定义的,模拟业务方法耗时,我直接 sleep 了 5s 确实没有占用 cpu;
真实的业务方法,包含查询 sql,调用外部接口,以及业务代码,估计也是没有一直占用 cpu 资源导致的吧?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/940138

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX