最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

IO密集型任務(wù)設(shè)置線程池線程數(shù)實(shí)現(xiàn)方式

 更新時(shí)間:2024年07月04日 09:46:58   作者:瘋狂佩奇  
這篇文章主要介紹了IO密集型任務(wù)設(shè)置線程池線程數(shù)實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

任務(wù)類型

CPU密集

CPU密集型的話,一般配置CPU處理器個(gè)數(shù)+/-1個(gè)線程,所謂CPU密集型就是指系統(tǒng)大部分時(shí)間是在做程序正常的計(jì)算任務(wù),例如數(shù)字運(yùn)算、賦值、分配內(nèi)存、內(nèi)存拷貝、循環(huán)、查找、排序等,這些處理都需要CPU來完成。

IO密集

IO密集型的話,是指系統(tǒng)大部分時(shí)間在跟I/O交互,而這個(gè)時(shí)間線程不會(huì)占用CPU來處理,即在這個(gè)時(shí)間范圍內(nèi),可以由其他線程來使用CPU,因而可以多配置一些線程。(線程處于io等待或則阻塞狀態(tài)時(shí),不會(huì)占用CPU資源)

混合型

混合型的話,是指兩者都占有一定的時(shí)間。

實(shí)際上工作中的大部分場(chǎng)景中,線程池的能力往往會(huì)超出想象。

測(cè)試準(zhǔn)備

下面的計(jì)算方式很粗略,而且有漏洞,但是也可以作為一個(gè)參考

處理器信息

四核8線程 (超線程

任務(wù)示例

我們首先確認(rèn)一下單個(gè)任務(wù)的io時(shí)間占比,下面是測(cè)試代碼

class ThreadPoolTest {
 
    public static int PARK_TIME = 0;
 
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        runTask(1);
    }
 
    public static void runTask(int threadNum) throws ExecutionException, InterruptedException {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
            threadNum, threadNum, 1, TimeUnit.SECONDS, new LinkedBlockingDeque<>(100)
        );
 
        long start = System.currentTimeMillis();
        List<Future<?>> taskList = new ArrayList<>();
        for (int i = 0; i < 1; i++) {
            taskList.add(threadPoolExecutor.submit(() -> {
                doJob();
            }));
        }
        for (Future<?> future : taskList) {
            future.get();
        }
        long time = System.currentTimeMillis() - start;
        System.out.println(threadNum + "個(gè)線程,耗時(shí):" + time + "停頓占比" + (PARK_TIME * 100.0 / time));
        threadPoolExecutor.shutdown();
    }
 
 
    public static Long doJob() {
        long result = 0L;
        PARK_TIME = 0;
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
            if (i % 10_000_000 == 0) {
                try {
                    ++PARK_TIME;
                    // 模擬IO
                    LockSupport.parkNanos(100_000_000);
                } catch (Exception ignore) {
                }
            }
            result += i;
        }
        return result;
    }
}

執(zhí)行結(jié)果

直接運(yùn)行 輸出如下:

1個(gè)線程,耗時(shí):27862停頓占比0.7716603258918958

也就是說大概77%的時(shí)間線程在睡覺。

分析

按我電腦的配置可以認(rèn)為核心數(shù)coreNum為8, 假設(shè)任務(wù)數(shù)夠多的情況下。

不考慮上下文切換等的耗時(shí),單個(gè)任務(wù)io耗時(shí)占比為x,在線程數(shù)最少的情況下想讓cpu利用率達(dá)到最高,可以得出一個(gè)等式 1 / (1 - x) * coreNum = 100% * coreNum(我們假設(shè)線程在活躍狀態(tài)時(shí)能完全占用單個(gè)核心)。

代入上面得到的值 x = 0.77, coreNum = 8 可以比較容易的算出來如果想讓cpu利用率達(dá)到最高, 1 / (1 - 0.77) * 8 約等于34。即線程池的線程數(shù)設(shè)置為35比較合理。

在我的電腦上合適的線程數(shù)和任務(wù)io耗時(shí)占比x的關(guān)系大致可以認(rèn)為 1 / (1 - x) * 8,即理論上的圖如下,這是一個(gè)非常粗糙的等式,實(shí)際上隨著線程數(shù)增多,上下文切換帶來的開銷越來越大,和下面這張圖的出入還是蠻大的。

不同線程數(shù)下的程序總執(zhí)行耗時(shí)

下面簡(jiǎn)單修改下程序來驗(yàn)證一下任務(wù)量固定,不同線程數(shù)下的程序執(zhí)行耗時(shí)。

代碼

class ThreadPoolTest {
    
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        List<Integer> threadNumList = Arrays.asList(4, 8, 16, 25, 34, 50);
        for (Integer threadNum : threadNumList) {
            runTask(threadNum);
        }
    }
 
    public static void runTask(int threadNum) throws ExecutionException, InterruptedException {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
            threadNum, threadNum, 1, TimeUnit.SECONDS, new LinkedBlockingDeque<>(100)
        );
 
        long start = System.currentTimeMillis();
        List<Future<?>> taskList = new ArrayList<>();
        for (int i = 0; i < 55; i++) {
            taskList.add(threadPoolExecutor.submit(() -> {
                doJob();
            }));
        }
        for (Future<?> future : taskList) {
            future.get();
        }
        long time = System.currentTimeMillis() - start;
        System.out.println(threadNum + "個(gè)線程,耗時(shí):" + time);
        threadPoolExecutor.shutdown();
    }
 
 
    public static Long doJob() {
        long result = 0L;
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
            if (i % 10_000_000 == 0) {
                try {
                    LockSupport.parkNanos(100_000_000);
                } catch (Exception ignore) {
                }
            }
            result += i;
        }
        return result;
    }
}

執(zhí)行結(jié)果

4個(gè)線程,耗時(shí):3670028個(gè)線程,耗時(shí):19075116個(gè)線程,耗時(shí):10835825個(gè)線程,耗時(shí):7863234個(gè)線程,耗時(shí):5315140個(gè)線程,耗時(shí):5356345個(gè)線程,耗時(shí):5519650個(gè)線程,耗時(shí):55729

期間cpu占用情況如下

總結(jié)

1.線程數(shù)從4-34期間耗時(shí)基本上穩(wěn)步縮減,但是線程數(shù)從34變成50的時(shí)候耗時(shí)并沒有明顯減少,反而有增加的趨勢(shì),只有cpu利用率一直在飆升。io密集型任務(wù)線程池任務(wù)的確有一個(gè)較優(yōu)解的,超過這個(gè)邊界再繼續(xù)增加線程數(shù),算力會(huì)被上下文切換給浪費(fèi)掉,在執(zhí)行CPU密集型任務(wù)時(shí)這個(gè)現(xiàn)象會(huì)更加明顯。

2.即使是50個(gè)線程的時(shí)候,算力依然有剩余,并沒有達(dá)到100%利用率。這是因?yàn)?,單個(gè)線程在活躍狀態(tài)下也并不能完全占用單個(gè)核心的所有時(shí)間片

3.每次任務(wù)執(zhí)行完都有一個(gè)小落差,這個(gè)可以自己思考一下為什么。

不同線程執(zhí)行耗時(shí) 以及資源利用率

34個(gè)線程,耗時(shí):60389
35個(gè)線程,耗時(shí):54077
36個(gè)線程,耗時(shí):54886
37個(gè)線程,耗時(shí):55035
38個(gè)線程,耗時(shí):55231
39個(gè)線程,耗時(shí):53961
40個(gè)線程,耗時(shí):53701
41個(gè)線程,耗時(shí):54406
42個(gè)線程,耗時(shí):54794
43個(gè)線程,耗時(shí):53585
44個(gè)線程,耗時(shí):52690
45個(gè)線程,耗時(shí):55242

最后

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • spring cloud gateway網(wǎng)關(guān)路由分配代碼實(shí)例解析

    spring cloud gateway網(wǎng)關(guān)路由分配代碼實(shí)例解析

    這篇文章主要介紹了spring cloud gateway網(wǎng)關(guān)路由分配代碼實(shí)例解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-01-01
  • SpringCloud?hystrix斷路器與局部降級(jí)全面介紹

    SpringCloud?hystrix斷路器與局部降級(jí)全面介紹

    什么是服務(wù)降級(jí)?當(dāng)服務(wù)器壓力劇增的情況下,根據(jù)實(shí)際業(yè)務(wù)情況及流量,對(duì)一些服務(wù)和頁(yè)面有策略的不處理或換種簡(jiǎn)單的方式處理,從而釋放服務(wù)器資源以保證核心交易正常運(yùn)作或高效運(yùn)作
    2022-10-10
  • JDBC實(shí)現(xiàn)數(shù)據(jù)庫(kù)增刪改查功能

    JDBC實(shí)現(xiàn)數(shù)據(jù)庫(kù)增刪改查功能

    這篇文章主要為大家詳細(xì)介紹了JDBC實(shí)現(xiàn)數(shù)據(jù)庫(kù)增刪改查功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • 利用JStack排查死鎖問題和CPU100%問題

    利用JStack排查死鎖問題和CPU100%問題

    無論是再面試過程中還是再實(shí)際項(xiàng)目開發(fā)當(dāng)中我們都有可能遇到這兩個(gè)問題如何利用JStack排查死鎖問題和CPU100%問題,文中給出了詳細(xì)的排查過程和解決方法,需要的朋友可以參考下
    2023-12-12
  • Java中利用BitMap位圖實(shí)現(xiàn)海量級(jí)數(shù)據(jù)去重

    Java中利用BitMap位圖實(shí)現(xiàn)海量級(jí)數(shù)據(jù)去重

    有許多方法可以用來去重,比如使用列表、集合等等,但這些方法通常只適用于一般情況,然而,當(dāng)涉及到大量數(shù)據(jù)去重時(shí),常見的 Java Set、List,甚至是 Java 8 的新特性 Stream 流等方式就顯得不太合適了,本文給大家介紹了Java中利用BitMap位圖實(shí)現(xiàn)海量級(jí)數(shù)據(jù)去重
    2024-04-04
  • spring-retry簡(jiǎn)單使用方法

    spring-retry簡(jiǎn)單使用方法

    這篇文章主要介紹了spring-retry簡(jiǎn)單使用方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-04-04
  • SpringBoot根據(jù)注解動(dòng)態(tài)執(zhí)行類中的方法實(shí)現(xiàn)

    SpringBoot根據(jù)注解動(dòng)態(tài)執(zhí)行類中的方法實(shí)現(xiàn)

    本文主要介紹了SpringBoot根據(jù)注解動(dòng)態(tài)執(zhí)行類中的方法實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-08-08
  • Spring?Data?JPA系列JpaSpecificationExecutor用法詳解

    Spring?Data?JPA系列JpaSpecificationExecutor用法詳解

    這篇文章主要為大家介紹了Spring?Data?JPA系列JpaSpecificationExecutor用法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • 詳解SpringBoot中文件上傳大小限制問題的解決方案

    詳解SpringBoot中文件上傳大小限制問題的解決方案

    在開發(fā)Web應(yīng)用程序時(shí),文件上傳是一個(gè)常見的需求,本文將詳細(xì)介紹如何分析和解決Spring Boot文件上傳大小限制問題,并提供多種配置方式,希望對(duì)大家有所幫助
    2025-07-07
  • Spring中@Transactional用法詳細(xì)介紹

    Spring中@Transactional用法詳細(xì)介紹

    這篇文章主要介紹了Spring中@Transactional用法詳細(xì)介紹的相關(guān)資料,需要的朋友可以參考下
    2017-02-02

最新評(píng)論

安多县| 宜良县| 永胜县| 垣曲县| 清丰县| 平乐县| 亚东县| 宝应县| 收藏| 临城县| 灵丘县| 志丹县| 新营市| 蛟河市| 灯塔市| 广河县| 班戈县| 浠水县| 密云县| 子长县| 水富县| 西平县| 兴海县| 志丹县| 绥化市| 镇康县| 南宫市| 万盛区| 黄大仙区| 军事| 沙坪坝区| 车险| 天水市| 宁阳县| 安化县| 若尔盖县| 莫力| 定南县| 武宁县| 临武县| 陆川县|