线程池

发布时间 2023-05-29 22:07:23作者: 永恒&

线程池

1、线程池的7个参数

  1. corePoolSize, 核心线程数,当新的任务到来时,如果当前核心线程的数量没有> 设置的值就新建一个线程执行该任务;否则,就将新任务放入工作队列/等待队列中
  2. maximumPoolSize,线程池的最大线程数,当新任务到来时,如果 当前线程数量 >= maximumPoolSize ,执行拒绝策略 handler;否则,
    1. 将任务加入工作队列当前线程数量 == corePoolSize && workQueue 未满
    2. 或者新建核心线程执行当前线程数量 < corePoolSize
    3. 或者新建工作线程执行当前线程数量 == corePoolSize && workQueue 以满
  3. keepAliveTime, 保活时间,一个线程空闲的最长时间,long型,单位由unit决定。
    1. 默认只会对非核心线程起作用,可以通过threadPoolExecutor.allowCoreThreadTimeOut(true);设置为对核心线程起作用,此时,必须满足keepAliveTime>0 ,因为核心线程必须存活时间大于0;否则会抛出 IllegalArgumentException("Core threads must have nonzero keep alive times"); 异常
  4. unit, 保活时间的单位,取值从TimeUnit这个枚举类中取值
  5. workQueue, 当新的任务到来时,如果,当前线程数量 == corePoolSize && workQueue 未满 ,将任务加入工作队列
    1. ArrayBlockingQueue 数组型阻塞队列
    2. LinkedBlockingQueue 链表型阻塞队列
    3. DelayQueue 延时队列
    4. SynchronousQueue 同步队列
    5. PriorityBlockingQueue 优先阻塞队列
    6. 各个任务队列的特点
    7. 可重入锁
  6. threadFactory, 线程工厂,可以使用自定义的线程工程,自定义线程名字的前缀,方便排查问题
  7. handler, 拒绝策略,当当前的线程数量 == maximumPoolSize && workQueue 已满,执行拒绝策略
    1. ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
    2. ThreadPoolExecutor.DiscardPolicy:丢弃任务,但是不抛出异常
    3. ThreadPoolExecutor.DiscardOldestPolicy丢弃队列最前面的任务,然后重新提交被拒绝的任务
    4. ThreadPoolExecutor.CallerRunsPolicy:由调用线程(提交任务的线程)处理该任务

在这里插入图片描述

2、简单使用

package org.example;

import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.springframework.scheduling.concurrent.CustomizableThreadFactory;

import java.util.concurrent.*;

@Slf4j
public class ThreadPoolTest {

    @Test
    public void ThreadPoolCreateTest() {
        // 线程池参数 初始化
        int corePoolSize = 2;
        int maximumPoolSize = 3;
        long keepAliveTime = 0L;
        TimeUnit unit = TimeUnit.MILLISECONDS;
        BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(1);
        ThreadFactory threadFactory = new CustomizableThreadFactory("GROUP");
        RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
		
        // 创建线程池
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                corePoolSize,
                maximumPoolSize,
                keepAliveTime,
                unit,
                workQueue,
                threadFactory,
                handler
        );


        long taskCount = threadPoolExecutor.getTaskCount();
//        threadPoolExecutor.allowCoreThreadTimeOut(true);  // 要是用这个,必须同步把 keepAliveTime 设置为 > 0
        log.info("taskCount : {}", taskCount);


        // 新建task
        Runnable Runnable = new Runnable() {
            @Override
            public void run() {
                log.info("ThreadName : {}", Thread.currentThread().getName());
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    log.error("{}", e);
                }
            }
        };

        // 线程池调用
        for (int i = 0; i < 10; i++) {
            System.out.println(i);
            threadPoolExecutor.execute(Runnable);
        }
    }
}
21:46:24.433 [main] INFO org.example.ThreadPoolTest - taskCount : 0
0
1
2
3
4
21:46:24.436 [GROUP1] INFO org.example.ThreadPoolTest - ThreadName : GROUP1 // i = 0
21:46:24.436 [GROUP2] INFO org.example.ThreadPoolTest - ThreadName : GROUP2 // i = 1
21:46:24.436 [GROUP3] INFO org.example.ThreadPoolTest - ThreadName : GROUP3 // i = 3

说明:

  • 当想要创建第四个线程的时候,发生了异常 因为 maximumPoolSize=3
  • 当 i=0和1的时候,创建的是核心线程,执行了任务,sleep
  • 当i=2时,任务进入工作队列
  • 当i=3时,任务被新建的工作线程执行
  • 当i=4时,任务到来时,发现当前线程池的线程数==maximumPoolSize,并且工作队列已满,所以抛出异常