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