面试题答案
一键面试- 核心线程数设定:
CompletableFuture
默认使用的线程池是ForkJoinPool.commonPool()
,这个公共线程池的核心线程数是Runtime.getRuntime().availableProcessors() - 1
(如果结果小于1,则使用1)。
- 获取核心线程数的方法:
这里ForkJoinPool forkJoinPool = ForkJoinPool.commonPool(); int corePoolSize = forkJoinPool.getParallelism();
getParallelism()
方法返回的是公共线程池的并行级别,其本质上等同于核心线程数(因为ForkJoinPool
的实现特性,它没有区分核心线程数和最大线程数,getParallelism()
返回的是可同时执行任务的最大线程数)。 - 这样设计的原因:
- 充分利用CPU资源:设定为
Runtime.getRuntime().availableProcessors() - 1
,是为了在多核CPU环境下,在运行CompletableFuture
任务的同时,还能为其他线程(比如主线程或者其他应用线程)保留一个CPU核心资源,避免因为所有CPU核心都被CompletableFuture
任务占用,导致系统整体响应性变差。如果结果小于1,则使用1,这样能保证至少有一个线程来处理异步任务。 - 减少线程上下文切换开销:通过使用一个相对固定大小的线程池(核心线程数相对固定),可以减少线程频繁创建和销毁带来的上下文切换开销,提高异步任务执行的效率。同时,公共线程池的设计可以让多个
CompletableFuture
任务复用这些线程,进一步提升资源利用率。
- 充分利用CPU资源:设定为