Java線程池ThreadPoolExecutor及自定義線程池

多線程線程池和自定義線程池 - 簡書
https://www.jianshu.com/p/0d548f0646fc

(1條消息)Java線程池ThreadPoolExecutor及自定義線程池_Java_零度的博客專欄-CSDN博客
https://blog.csdn.net/zmx729618/article/details/78839284

線程池參數
corePoolSize:線程池核心線程數量,核心線程不會被回收,即使沒有任務執行,也會保持空閒狀態。
maximumPoolSize:線程池允許最大的線程數,當線程數量達到corePoolSize,且workQueue隊列塞滿任務了之後,繼續創建線程,優先級提高。
keepAliveTime:超過corePoolSize之後的存活時間
unit:keepAliveTime的單位。
workQueue:當前線程數超過corePoolSize時,新的任務會處在等待狀態,並存在workQueue中,BlockingQueue是一個先進先出的阻塞式隊列實現,底層實現會涉及Java併發的AQS機制,有關於AQS的相關知識,我會單獨寫一篇,敬請期待。
threadFactory:創建線程的工廠類
handler:線程池執行拒絕策略.當線數量達到maximumPoolSize大小,並且workQueue也已經塞滿了任務的情況下,線程池會調用handler拒絕策略來處理請求。
拓展:
常見的拒絕策略:

AbortPolicy:爲線程池默認的拒絕策略,該策略直接拋異常處理。
DiscardPolicy:直接拋棄不處理。
DiscardOldestPolicy:丟棄隊列中最老的任務。
CallerRunsPolicy:將任務分配給當前執行execute方法線程來處理。

線程池的基礎上,自定義線程池

ThreadPoolExecutor

        Executors.newFixedThreadPool(10);
        Executors.newCachedThreadPool();
        Executors.newSingleThreadExecutor();
        Executors.newWorkStealingPool();
        Executors.newScheduledThreadPool(10);

newCachedThreadPool()源碼

    public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

newFixedThreadPool()源碼

    public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

共同點:

        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());

依據源碼自定義線程池:

new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);

自定義線程,實現Runnable

public class MyTask implements Runnable {

    //自定義線程ID
    private int taskId;
    //線程名稱
    private String taskName;

    public MyTask(int taskId, String taskName) {
        this.taskId = taskId;
        this.taskName = taskName;
    }

    public int getTaskId() {
        return taskId;
    }

    public void setTaskId(int taskId) {
        this.taskId = taskId;
    }

    public String getTaskName() {
        return taskName;
    }

    public void setTaskName(String taskName) {
        this.taskName = taskName;
    }
    public void run() {
        try {
            System.out.println("當前線程Id-->" + taskId + ",任務名稱-->" + taskName);
            Thread.sleep(5 * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

main函數


public class CustomerThreadPool {

    public static void main(String[] args) {
        //這裏使用的是有界隊列,不是無界隊列
        ThreadPoolExecutor pool = new ThreadPoolExecutor(2, 2, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(3));

        MyTask task1 = new MyTask(1, "任務1");
        MyTask task2 = new MyTask(2, "任務2");
        MyTask task3 = new MyTask(3, "任務3");
        MyTask task4 = new MyTask(4, "任務4");
        MyTask task5 = new MyTask(5, "任務5");
        MyTask task6 = new MyTask(6, "任務6");

        
        pool.execute(task1);
        pool.execute(task2);
        pool.execute(task3);
        pool.execute(task4);
        pool.execute(task5);
    }
}
當前線程Id-->5,任務名稱-->任務5
當前線程Id-->1,任務名稱-->任務1
當前線程Id-->2,任務名稱-->任務2
當前線程Id-->3,任務名稱-->任務3
當前線程Id-->4,任務名稱-->任務4

原因在於,新建的有界隊列只有3,除去當前執行的進程,線程池還能存放3個進程,因此當線程5放入的時候,隊列滿,則會新建線程去執行,優先級提高

真·自定義線程池

(1條消息)Java線程池ThreadPoolExecutor及自定義線程池_Java_零度的博客專欄-CSDN博客
https://blog.csdn.net/zmx729618/article/details/78839284

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章