手動實現線程池 ThreadPool


Executors提供了三個經典的線程池創建方式

ExecutorService threadPool = Executors.newFixedThreadPool(int)

ExecutorService threadPool = Executors.newSingleThreadPool()
ExecutorService threadPool = Executors.newCachedThreadPool(int)

那我們在工作中到底用哪一個呢?

答案是我們在生產上只能用自定義的

根據圖中我們可以發現他們得底層實現都是用了ThreadPoolExecutor,然而第五個參數使用到的阻塞隊列默認值是Integer.MAX_VALUE,也就是

2147483647,這樣就相當於是一個無界的隊列。所有的請求都往里塞,最終造成OOM。

根據阿里編碼規范也可以看出

參數說明

線程池底層實現的7大參數
1.corePoolSize:線程池中的常駐核心線程數
2.maximumPoolSize:線程池能夠容納同時執行的最大線程數,此值必須大於等於1
3.keepAliveTime:多余的空閑線程的存活時間
4.unit:keepAliveTime的單位
5.workQueue:任務隊列,被提交但尚未被執行的任務。
6.threadFactory:表示生成線程池中工作線程的線程工廠,用於創建線程一般用默認
7.handler:拒絕策略,表示當隊列滿了並且工作線程大於等於線程池的最大線程數

工作原理

線程池的底層工作原理
core基本線程數,當線程數大於corePoolSize時,多余線程將轉入阻塞隊列,阻塞隊列也滿了之后
將擴容到maximumPoolSize數。maximumPoolSize也滿了之后將采取拒絕策略。
當線程數小了之后,根據設定的空閑線程存活時間將線程總容量回縮到corePoolSize

手動實現

/**
* 線程池demo
* @author t
* 實際工作中對多線程的使用都是線程池,不會顯示的創建線程
* 而使用傳統方式的方法創建線程池容易造成oom
*/
public class ThreadPoolDemo {
    public static void main(String[] args) {
        ExecutorService threadPool = new ThreadPoolExecutor(
                2,
                5,
                1,
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());
        try {
            for (int i = 1; i <= 10; i++) {
                final int num = i;
                threadPool.execute(() -> {
                    //打印當前線程名稱
                    //暫停一會線程
                    System.out.println("序號 "+num+"  "+Thread.currentThread().getName()+" \t 辦理業務");
                });
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            threadPool.shutdown();
        }
    }
}

運行結果

注意:根據機器配置不同運行效果也不同,本來應該是超過最大線程數(maximumPoolSize+隊列大小)就會觸發拒絕策略,但是由於機器處理速度

能夠處理的過來,所以沒有報錯。

線程暫停1秒,9個線程的運行結果

 

作者:ushowtime

原文地址:https://www.ushowtime.cn/blog/p/50


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM