多个CPU--多核--核心线程数理解
今天在创建简单线程池时,使用 Runtime.getRuntime().availableProcessors() 有些不懂网上这么配置的理由,百度说是计算资源(逻辑核心数)与 CPU 有关,但是和 CPU 具体啥关系还是一知半解,今天通过看资料,整理一下我的理解。
import com.google.common.util.concurrent.ThreadFactoryBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import java.util.concurrent.*; /** * @author yangchao * @description 线程池配置 * @date 2024/05/20 */ @Configuration public class ThreadPoolInitConfig { public static final String TEST_THREAD_POOL_NAME = "TEST_THREAD_POOL_NAME-%d"; @Bean(name = "testExecutorService") public ExecutorService testExecutorService() { ThreadFactory namedThreadFactory = new ThreadFactoryBuilder() .setNameFormat(TEST_THREAD_POOL_NAME).build(); ExecutorService threadPoolExecutor = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors() * 2 + 1, Runtime.getRuntime().availableProcessors() * 2 + 1, 0L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(), namedThreadFactory); return threadPoolExecutor; } }
简单使用
@Resource(name = "testExecutorService") private ExecutorService testExecutorService; @RequestMapping("/testThreadPool") @ResponseBody public String testThreadPool() { testExecutorService.execute(() -> { // 并发执行子任务的逻辑 }); return "主线程执行完成!"; }
第二种初始化线程池方式
package com.helios.util; import java.util.concurrent.ExecutorService; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; /** * @author yangchao * @date 2024/07/05 * @description 线程池工具类 **/ public class ThreadUtils { /** * 定义线程池处理 */ private static ExecutorService executor; /** * 初始化线程池 */ static { // 构建一个线程池 // Runtime.getRuntime().availableProcessors() 返回可用处理器的Java虚拟机的数量 executor = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors() * 2 + 1, Runtime.getRuntime().availableProcessors() * 2 + 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(10000)); } /** * 线程执行一个任务 */ public static void execute(Runnable task) { executor.execute(task); } /** * 消除线程池的所有线程 */ public static void destory() { executor.shutdown(); } }
举例说明
【1】例如你需要搬100块砖,你现在有50双手。当你将这50双手全安装到一个人身上,这模式就是CPU多核处理器。当你将这50双手安装到50个人身上工作,这模式就是多个CPU,每个人有2只手,分别都可以搬一块砖,这相当于支持超线程cpu, 即有50个物理核心数,每个物理核心数有2个逻辑核心数,即一共有100个逻辑核心数;
【2】将50双手放在一个人身上,会带来一些问题,例如同时搬100块砖,身体就会顶不住,这就是CPU多核的极限。于是,当要搬的砖较多的时候,多个CPU的方式就显现出来了,人多力量大呀;
【3】多核CPU与多个CPU并不冲突,相反,两者会相互结合。目前有些大型机经常会有多个CPU,每个CPU都是多核的。比如50个物理CPU,每个物理CPU都有2个核,那么最终的CPU就是100核的。
结论
Runtime.getRuntime().availableProcessors() 返回的是可用的计算资源,而不是CPU物理核心数,对于支持超线程的CPU来说,单个物理处理器相当于拥有2个逻辑处理器,能够同时执行2个线程。
Runtime.getRuntime().availableProcessors() // 我的电脑输出是:8 即同时会有8个线程处理8个任务