欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

關(guān)于線程池異步線程中再次獲取線程池資源的問題

 更新時間:2024年08月20日 10:33:56   作者:BlueKitty1210  
這篇文章主要介紹了關(guān)于線程池異步線程中再次獲取線程池資源的問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

問題描述

在線上發(fā)生的一次問題,在場景中有這樣一個業(yè)務(wù),需要異步執(zhí)行一個主任務(wù),主任務(wù)中又包含著N個子任務(wù),為了整個主任務(wù)能夠快速處理,又將子任務(wù)按照數(shù)量獲取線程資源異步處理,即異步線程A中再異步調(diào)用A1,A2,A3. A可能同時存在多個.

實際場景中,由于系統(tǒng)線程池分配數(shù)量較小,且一段時間內(nèi)先后啟動了多個主任務(wù),耗時的主任務(wù)中又用子任務(wù)取申請線程導(dǎo)致線程池資源耗盡

問題原因

1. 主任務(wù)是從線程池中獲取的線程資源,同時主任務(wù)比較耗時?

2. 每個主任務(wù)中包含的N的子任務(wù),會再申請線程,處理完畢釋放回線程池

3. 啟動了多個主任務(wù)時,每個主任務(wù)在未結(jié)束之前,都會占用自身一個線程不會釋放,消耗一個線程池資源

4. 后期頻繁啟動主任務(wù),可能使數(shù)量=線程池線程數(shù),此時子任務(wù)無法再從線程池獲得資源,就進(jìn)入隊列等待

5. 最終結(jié)果就造成了每個主任務(wù)都占用線程,但主任務(wù)內(nèi)的子任務(wù)無法獲取線程,線程池癱瘓不可用

問題復(fù)現(xiàn)

package test;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomUtils;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @title 線程池異步線程中再次獲取線程池資源的問題
 * @author Xingbz
 * @description
 *  記;
 *
 *  究其原因在于:
 *      
 * @createDate 2020-7-17
 */
@Slf4j
public class TestWork {

    private static final ThreadPoolTaskExecutor EXECUTOR;

    static {
        EXECUTOR = myExecutor();
    }

    /** 初始化線程池 */
    public static ThreadPoolTaskExecutor myExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 核心線程數(shù)
        executor.setCorePoolSize(5);
        // 最大線程數(shù)
        executor.setMaxPoolSize(20);
        // 排隊任務(wù)隊列
        executor.setQueueCapacity(100);
        // 線程名稱前綴
        executor.setThreadNamePrefix("異步線程-");
        // 隊列滿后拒絕策略
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 線程最大回收時間
        executor.setKeepAliveSeconds(100);
        // 初始化線程
        executor.initialize();
        return executor;
    }

    /** 模擬測試 */
    public static void main(String[] args) throws Exception {
        // 主任務(wù)數(shù)量
        int mainJobNum = 20;

        CountDownLatch mainDownLatch = new CountDownLatch(mainJobNum);

        for (int i = 0; i < mainJobNum; i++) {
            // 主任務(wù)編號, 方便區(qū)分
            int index = i + 1;

            // 模擬每1秒開始一個主任務(wù)
            TimeUnit.SECONDS.sleep(1);

            EXECUTOR.submit(() -> {
                try {
                    log.debug("\t執(zhí)行主任務(wù)" + index);

                    // 每個主任務(wù)隨機(jī)包含N個子任務(wù), 再異步調(diào)用線程池資源處理
                    int subJobNum = RandomUtils.nextInt(2, 3);
                    subJobWorkAsync(subJobNum, index);
                } finally {
                    mainDownLatch.countDown();
                }
            });
        }

        mainDownLatch.await();
        EXECUTOR.shutdown();
        log.info("完成所有任務(wù) > > >");
    }

    /** 異步執(zhí)行子任務(wù) */
    private static void subJobWorkAsync(int subJobNum, int index) {
        CountDownLatch subDownLatch = new CountDownLatch(subJobNum);
        for (int j = 0; j < subJobNum; j++) {
            EXECUTOR.submit(() -> {
                try {
                    log.warn("\t\t\t執(zhí)行一個" + index + "的子任務(wù)");
                    // 每個子任務(wù)模擬耗時
                    TimeUnit.SECONDS.sleep(3);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    subDownLatch.countDown();
                }
            });
        }

        try {
            subDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

執(zhí)行代碼,結(jié)果如下:

可以看到,線程池很快就被主任務(wù)耗盡, 導(dǎo)致子任務(wù)無法執(zhí)行.

解決方案

1. 異步線程中不能再獲取異步線程

既然主方法是異步執(zhí)行了,那么其中的子任務(wù)也相對不那么要求時間.此處是我為了業(yè)務(wù)給另外一個業(yè)務(wù)復(fù)用導(dǎo)致了線程再調(diào)線程

2. 如果異步中確實需要再獲取異步線程,需要使用新的線程池. 不能再使用自身的線程池

這是當(dāng)前我們的解決方案,在系統(tǒng)中又單獨(dú)構(gòu)建了一個線程池負(fù)責(zé)子任務(wù)的業(yè)務(wù)

總結(jié)

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

相關(guān)文章

  • 流式圖表拒絕增刪改查之kafka核心消費(fèi)邏輯上篇

    流式圖表拒絕增刪改查之kafka核心消費(fèi)邏輯上篇

    這篇文章主要為大家介紹了流式圖表拒絕增刪改查之kafka核心消費(fèi)邏輯詳解的上篇,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • Java實現(xiàn)簡單計算器小程序

    Java實現(xiàn)簡單計算器小程序

    這篇文章主要為大家詳細(xì)介紹了Java實現(xiàn)簡單計算器小程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • Spring中Xml屬性配置的解析全過程記錄

    Spring中Xml屬性配置的解析全過程記錄

    這篇文章主要給大家介紹了關(guān)于Spring中Xml屬性配置的解析全過程,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • Java.SE數(shù)組的一些常見練習(xí)題

    Java.SE數(shù)組的一些常見練習(xí)題

    數(shù)組可以看成是相同類型元素的一個集合,在內(nèi)存中是一段連續(xù)的空間,這篇文章主要給大家介紹了關(guān)于Java.SE數(shù)組的一些常見練習(xí)題,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-02-02
  • Java并發(fā)編程中的ReentrantLock類詳解

    Java并發(fā)編程中的ReentrantLock類詳解

    這篇文章主要介紹了Java并發(fā)編程中的ReentrantLock類詳解,ReentrantLock是juc.locks包中的一個獨(dú)占式可重入鎖,相比synchronized,它可以創(chuàng)建多個條件等待隊列,還支持公平/非公平鎖、可中斷、超時、輪詢等特性,需要的朋友可以參考下
    2023-12-12
  • Java反射之通過反射獲取一個對象的方法信息(實例代碼)

    Java反射之通過反射獲取一個對象的方法信息(實例代碼)

    下面小編就為大家?guī)硪黄狫ava反射之通過反射獲取一個對象的方法信息(實例代碼)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-10-10
  • Spring整合mybatis、springMVC總結(jié)

    Spring整合mybatis、springMVC總結(jié)

    這篇文章主要為大家詳細(xì)介紹了Java整合Mybatis,SpringMVC,文中有詳細(xì)的代碼示例,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2023-05-05
  • 詳解Spring全局異常處理的三種方式

    詳解Spring全局異常處理的三種方式

    這篇文章主要介紹了詳解Spring全局異常處理的三種方式,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-04-04
  • SpringBoot整合微信登錄功能的實現(xiàn)方案

    SpringBoot整合微信登錄功能的實現(xiàn)方案

    今天通過本文給大家分享微信登錄與SpringBoot整合過程,微信掃描登錄實現(xiàn)代碼知道掃描后點(diǎn)擊登錄的全部過程,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2021-10-10
  • java實現(xiàn)將ftp和http的文件直接傳送到hdfs

    java實現(xiàn)將ftp和http的文件直接傳送到hdfs

    前面幾篇文章,我們已經(jīng)做了很好的鋪墊了,幾個要用到的工具我們都做了出來,本文就是將他們集合起來,說下具體的用法,小伙伴們可以參考下。
    2015-03-03

最新評論