ThreadPoolExecutor使用方法


先看構造方法 ,ThreadPoolExecutor共4個構造方法:

 直接看參數最多的7個參數分別代表:

public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,  TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler)
  • corePoolSize: 線程池核心線程數
  • maximumPoolSize:線程池最大數
  • keepAliveTime: 空閑線程存活時間
  • unit: 時間單位
  • workQueue: 線程池所使用的緩沖隊列
  • threadFactory:線程池創建線程使用的工廠
  • handler: 線程池對拒絕任務的處理策略

1.當池中正在運行的線程數(包括空閑線程數)小於corePoolSize時,新建線程執行任務

 public static void main(String[] args) {
        ThreadPoolExecutor pool = new ThreadPoolExecutor(2, 3, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1));
        // 任務1
        pool.execute(() -> {
            try {
                Thread.sleep(3 * 1000);
                System.out.println("--helloWorld_001--" + Thread.currentThread().getName());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        //任務2
        pool.execute(() -> System.out.println("--helloWorld_002--" + Thread.currentThread().getName()));
}

結論:線程1 結束后 沒有繼續線程1 而是啟動線程2

2.當池中正在運行的線程數(包括空閑線程數)大於等於corePoolSize時,新插入的任務進入workQueue排隊(如果workQueue長度允許),等待空閑線程來執行。

    public static void main(String[] args) {
        ThreadPoolExecutor pool = new ThreadPoolExecutor(2, 3, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1));
        // 任務1
        pool.execute(() -> {
            try {
                Thread.sleep(3 * 1000);
                System.out.println("--helloWorld_001--" + Thread.currentThread().getName());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        // 任務2
        pool.execute(() -> {
            try {
                Thread.sleep(5 * 1000);
                System.out.println("--helloWorld_002--" + Thread.currentThread().getName());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        // 任務3
        pool.execute(() -> System.out.println("--helloWorld_003--" + Thread.currentThread().getName()));
}

 結論:任務2在運行過程中,任務3啟動不會新建線程,因為有一個隊列是空的,maximumPoolSize=3這個參數不起作用。

3.當隊列里的任務達到上限,並且池中正在進行的線程小於maxinumPoolSize,對於新加入的任務,新建線程。

 public static void main(String[] args) {
        ThreadPoolExecutor pool = new ThreadPoolExecutor(2, 3, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1));
        // 任務1
        pool.execute(() -> {
            try {
                Thread.sleep(3 * 1000);
                System.out.println("--helloWorld_001--" + Thread.currentThread().getName());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        // 任務2
        pool.execute(() -> {
            try {
                Thread.sleep(5 * 1000);
                System.out.println("--helloWorld_002--" + Thread.currentThread().getName());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        // 任務3
        pool.execute(() -> System.out.println("--helloWorld_003--" + Thread.currentThread().getName()));
        // 任務4
        pool.execute(() -> System.out.println("--helloWorld_004--" + Thread.currentThread().getName()));
    }

結果:任務1,2啟動后 任務3在隊列 ,隊列就滿了,由於正在進行的線程數是2<maximumPoolSize,只能新建一個線程了 然后任務4就進了新線程-3,任務4結束,隊列里的任務3在線程3 進行。

4.隊列里的任務達到上限,並且池中正在運行的線程等於maximumPoolSize,對於新加入的任務,執行拒絕策略(線程池默認的策略是拋異常)。

public static void main(String[] args) {
        ThreadPoolExecutor pool = new ThreadPoolExecutor(2, 3, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1));
        // 任務1
        pool.execute(() -> {
            try {
                Thread.sleep(3 * 1000);
                System.out.println("--helloWorld_001--" + Thread.currentThread().getName());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        // 任務2
        pool.execute(() -> {
            try {
                Thread.sleep(5 * 1000);
                System.out.println("--helloWorld_002--" + Thread.currentThread().getName());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        // 任務3
        pool.execute(() -> System.out.println("--helloWorld_003--" + Thread.currentThread().getName()));
        // 任務4
        pool.execute(() -> {
            try {
                Thread.sleep(2 * 1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("--helloWorld_004--" + Thread.currentThread().getName());
        });
        // 任務5
        pool.execute(() -> System.out.println("--helloWorld_005--" + Thread.currentThread().getName()));
    }
運行結果:
Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task ExecutorDemo$$Lambda$5/999966131@7699a589 rejected from java.util.concurrent.ThreadPoolExecutor@58372a00[Running, pool size = 3, active threads = 3, queued tasks = 1, completed tasks = 0]
    at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2063)
    at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:830)
    at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1379)
    at ExecutorDemo.main(ExecutorDemo.java:40)
--helloWorld_004----pool-1-thread-3
--helloWorld_003--pool-1-thread-3
--helloWorld_001--pool-1-thread-1
--helloWorld_002--pool-1-thread-2

結論:隊列達到上限,線程池達到最大值,故拋出異常。


免責聲明!

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



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