多个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个任务

 

posted @ 2024-05-20 11:17  菜鸟的奋斗之路  阅读(30)  评论(0编辑  收藏  举报