Java自定義參數創建線程池


本文主要介紹了Java自定義參數創建線程池的示例,其中也使用了java的並發工具類CountDownLatch和CyclicBarrier(順便練習一下他們的用法),記錄第一次發博客

使用線程池的好處

  • 降低資源消耗。通過重復利用已創建的線程降低線程創建和銷毀造成的消耗。
  • 提高響應速度。當任務到達時,任務可以不需要的等到線程創建就能立即執行。
  • 提高線程的可管理性。線程是稀缺資源,如果無限制的創建,不僅會消耗系統資源,還會降低系統的穩定性,使用線程池可以進行統一的分配,調優和監控。

通過Executors工具類創建的線程池的弊端

  • FixedThreadPool 和SingleThreadExecutor使用無界隊列 LinkedBlockingQueue(隊列的容量為 Intger.MAX_VALUE)作為線程池的工作隊列,可能堆積大量的請求,從而導致 OOM。
  • ScheduledThreadPoolExecutor使用無界隊列DelayQueue(隊列的容量為 Intger.MAX_VALUE)作為線程池的工作隊列,可能堆積大量的請求,從而導致 OOM。
  • CachedThreadPool允許創建的線程數量為 Integer.MAX_VALUE ,可能會創建大量線程,從而導致 OOM。

 

自定義參數創建線程池示例

package thread;

import java.util.concurrent.*;

public class ThreadPoolDemo {

    //線程池的核心線程數量
    private static final int CORE_POOL_SIZE = 5;
    //線程池的最大線程數
    private static final int MAX_POOL_SIZE = 10;
    //阻塞隊列的容量
    private static final int QUEUE_CAPACITY = 100;
    //當線程數大於核心線程數時,多余的空閑線程存活的最長時間
    private static final Long KEEP_ALIVE_TIME = 1L;

    public static int threadNum = 5;

    public static void main(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(threadNum);
        CyclicBarrier cyclicBarrier = new CyclicBarrier(threadNum);

        //使用阿里巴巴推薦的創建線程池的方式
        //通過ThreadPoolExecutor構造函數自定義參數創建
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                CORE_POOL_SIZE,
                MAX_POOL_SIZE,
                KEEP_ALIVE_TIME,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(QUEUE_CAPACITY),

                //線程池達到飽和之后的拒絕策略,
                // 調用執行自己的線程運行任務,也就是直接在調用execute方法的線程中運行被拒絕的任務
                new ThreadPoolExecutor.CallerRunsPolicy());


        for (int i = 0; i < threadNum; i++) {
            //簡潔的Lambda表達式
            executor.execute(() -> {
                try {
                    //當前線程阻塞,直到所有線程都准備就緒
                    cyclicBarrier.await();
                    System.out.println( "當前線程: "+ Thread.currentThread().getName() + " 開始工作啦");
                    //模擬業務代碼
                    Thread.sleep(1000);
                    System.out.println( "當前線程: "+ Thread.currentThread().getName() + " 結束工作啦");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }

                countDownLatch.countDown();

            });
        }
        //主線程等待工作線程全部結束
        countDownLatch.await();
        //關閉線程池
        executor.shutdown();

        System.out.println("全部線程工作完成");
    }
}

 


免責聲明!

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



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