10、JUC、執行緒池(重點)

很皮的皮蛋瘦肉粥發表於2020-11-07


執行緒池:三大型別、七大引數、四種拒絕策略

10.1、池化技術

程式的執行,本質:佔用系統的資源! 優化資源的使用! =》池化技術

執行緒池、連線池、記憶體池、物件池… 建立、銷燬,十分浪費資源

池化技術:事先準備好一些資源,有人要用,就來我這裡拿,用完之後還給我

執行緒池的好處:

1、降低資源消耗

2、提高響應速度

3、方便管理

執行緒複用、可以控制最大併發數、管理執行緒

10.2、三大方法

在這裡插入圖片描述
方法一:newSingleThreadExecutor()

方法二:newFixedThreadPool()

方法三:newCachedThreadPool()

package com.chen.pool;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

// Executors 工具類,3大方法
// 使用了執行緒池
public class Demo01 {

    public static void main(String[] args) {
        // 建立一個單個執行緒的執行緒池
        ExecutorService threadPool = Executors.newSingleThreadExecutor();

        // 建立一個大小固定的執行緒池
        // ExecutorService threadPool = Executors.newFixedThreadPool(5);

        // 可伸縮的,遇強則強,遇弱則弱
        // ExecutorService threadPool = Executors.newCachedThreadPool();


        try {
            for (int i = 0; i < 10; i++) {
                threadPool.execute(() -> {
                    System.out.println(Thread.currentThread().getName() + "ok");
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 執行緒池用完,程式結束,關閉執行緒池
            threadPool.shutdown();
        }

    }
}

10.3、七大引數

原始碼分析

newSingleThreadExecutor()

public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1,
                                0L, TimeUnit.MILLISECONDS,
                                new LinkedBlockingQueue<Runnable>()));
}

newFixedThreadPool(5)

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

newCachedThreadPool()

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

本質:ThreadPoolExecutor

public ThreadPoolExecutor(int corePoolSize, // 核心執行緒池大小
                          int maximumPoolSize, // 最大執行緒池大小
                          long keepAliveTime, // 超時了沒有人呼叫就會釋放
                          TimeUnit unit, // 超時單位
                          BlockingQueue<Runnable> workQueue, // 阻塞佇列
                          ThreadFactory threadFactory, // 執行緒工程,建立執行緒的
                          RejectedExecutionHandler handler // 拒絕策略
                          ) {
    if (corePoolSize < 0 ||
        maximumPoolSize <= 0 ||
        maximumPoolSize < corePoolSize ||
        keepAliveTime < 0)
        throw new IllegalArgumentException();
    if (workQueue == null || threadFactory == null || handler == null)
        throw new NullPointerException();
    this.acc = System.getSecurityManager() == null ?
            null :
            AccessController.getContext();
    this.corePoolSize = corePoolSize;
    this.maximumPoolSize = maximumPoolSize;
    this.workQueue = workQueue;
    this.keepAliveTime = unit.toNanos(keepAliveTime);
    this.threadFactory = threadFactory;
    this.handler = handler;
}

在這裡插入圖片描述

10.4、手動建立執行緒池

package com.chen.pool;

import java.util.concurrent.*;

// Executors 工具類,3大方法

/**
 * 四種拒絕策略
 * 1、new ThreadPoolExecutor.AbortPolicy() // 銀行滿了,並且還有人進來,丟擲異常
 * 2、new ThreadPoolExecutor.CallerRunsPolicy() // 哪來的去哪裡
 * 3、new ThreadPoolExecutor.DiscardPolicy() // 佇列滿了,丟掉任務,不會丟擲異常
 * 4、new ThreadPoolExecutor.DiscardOldestPolicy() // 佇列滿了,嘗試去和最早的競爭,如果競爭失敗,依舊丟掉,不會報異常
 */

public class Demo01 {

    public static void main(String[] args) {

        // 自定義執行緒池
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
                2, // 核心執行緒池大小
                5, // 最大執行緒池大小
                3, // 超時了沒有人呼叫就會釋放
                TimeUnit.SECONDS, // 超時單位
                new LinkedBlockingDeque<>(3), // 阻塞佇列
                Executors.defaultThreadFactory(), // 執行緒工程,建立執行緒的
                new new ThreadPoolExecutor.AbortPolicy() // 佇列滿了,嘗試去和最早的競爭,如果競爭失敗,依舊丟掉,不會報異常
        );


        try {
            // 最大承載:Deque + max
            // 超過 RejectedExecutionException
            for (int i = 1; i <= 9; i++) {
                threadPool.execute(() -> {
                    System.out.println(Thread.currentThread().getName() + "ok");
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 執行緒池用完,程式結束,關閉執行緒池
            threadPool.shutdown();
        }

    }
}

10.5、四種拒絕策略

在這裡插入圖片描述
1、new ThreadPoolExecutor.AbortPolicy() // 銀行滿了,並且還有人進來,丟擲異常

在這裡插入圖片描述
2、new ThreadPoolExecutor.CallerRunsPolicy() // 哪來的去哪裡

在這裡插入圖片描述
3、new ThreadPoolExecutor.DiscardPolicy() // 佇列滿了,丟掉任務,不會丟擲異常

在這裡插入圖片描述
4、new ThreadPoolExecutor.DiscardOldestPolicy() // 佇列滿了,嘗試去和最早的競爭,如果競爭失敗,依舊丟掉,不會報異常

10.6、小結核擴充

池的最大的大小如何去設定!

瞭解:IO密集型,CPU密集型

package com.chen.pool;

import java.util.concurrent.*;

public class Demo01 {

    public static void main(String[] args) {

        // 自定義執行緒池

        // 最大執行緒池應該如何定義
        // 1、CPU 密集型 幾核,就是幾,可以保持CPU的效率最高
        // 2、IO 密集型 > 判斷你程式中十分耗IO的執行緒
        //        程式  15個大型任務  io十分佔用資源

        // 獲取CPU的核數
        System.out.println(Runtime.getRuntime().availableProcessors());

        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
                2,
                5,
                3,
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.DiscardOldestPolicy() // 佇列滿了,嘗試去和最早的競爭,如果競爭失敗,依舊丟掉,不會報異常
        );


        try {
            // 最大承載:Deque + max
            // 超過 RejectedExecutionException
            for (int i = 1; i <= 9; i++) {
                threadPool.execute(() -> {
                    System.out.println(Thread.currentThread().getName() + "ok");
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 執行緒池用完,程式結束,關閉執行緒池
            threadPool.shutdown();
        }

    }
}

學校視訊連結:https://www.bilibili.com/video/BV1B7411L7tE?p=24

相關文章