程序员必会之最详细的ThreadPoolExecutor 线程池七大参数含义

开发 后端
ThreadPoolExecutor 在创建之初,是不会立即初始化CorePoolSize数量的Thread的,而是通过外部Request来一个一个的创建,当达到CorePoolSize数目之后,就会维持至少CorePoolSize数目的Thread在pool中,哪怕他们都处于空闲状态(idle)。

线程池的 7 大参数整理。

public ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)

corePoolSize 线程池中长期存活的线程数

ThreadPoolExecutor 在创建之初,是不会立即初始化corePoolSize数量的Thread的,而是通过外部request来一个一个的创建,当达到corePoolSize数目之后,就会维持至少corePoolSize数目的Thread在pool中,哪怕他们都处于空闲状态(idle)。corePoolSize >= 0。

maximumPoolSize 线程池中的最大线程数量

maximumPoolSize >= corePoolSize,maximumPoolSize>0

  • 若当前线程池中线程数 < corePoolSize,则每来一个任务就创建一个线程去执行。
  • 若当前线程池中线程数 >= corePoolSize,会尝试将任务添加到任务队列。如果添加成功,则任务会等待空闲线程将其取出并执行(针对的是有界队列)。
  • 若队列已满,且当前线程池中线程数 < maximumPoolSize,创建新的线程。
  • 若当前线程池中线程数 >= maximumPoolSize,则会采用拒绝策略。

keepAliveTime 空闲线程存活时间

当线程池线程数量超过corePoolSize时,多余的空闲线程会在多长时间内被销毁。

销毁的线程数=maximumPoolSize(最大线程数)-corePoolSize(核心线程数)。

TimeUnit 时间单位

空闲线程存活时间的描述单位,有以下选项:

  • TimeUnit.DAYS:天
  • TimeUnit.HOURS:小时
  • TimeUnit.MINUTES:分
  • TimeUnit.SECONDS:秒
  • TimeUnit.MILLISECONDS:毫秒
  • TimeUnit.MICROSECONDS:微妙
  • TimeUnit.NANOSECONDS:纳秒

BlockingQueue

提交但未执行的任务队列,有以下选项:

  • LinkedBlockingQueue:用链表实现的队列,可以是有界的,也可以是无界的,但在Executors中默认使用无界的。当有新的任务来到时,若系统的线程数小于corePoolSize,线程池会创建新的线程执行任务, 当系统的线程数量等于corePoolSize后,因为是无界的任务队列,总是能成功将任务添加到任务队列中,所以线程数量不再增加。若任务创建的速度远大于任务处理的速度,无界队列会快速增长,直到内存耗尽。
  • SynchronousQueue:一个不存储元素的阻塞队列,SynchronousQueue没有容量,所以实际上提交的任务不会被添加到任务队列,总是将新任务提交给线程执行,如果没有空闲的线程,则尝试创建新的线程,如果线程数量已经达到最大值(maximumPoolSize),则执行拒绝策略。
  • ArrayBlockingQueue:一个由数组结构组成的有界阻塞队列。
  • PriorityBlockingQueue:一个支持优先级排序的无界阻塞队列。
  • DelayQueue:一个使用优先级队列实现的无界阻塞队列,只有在延迟期满时才能从中提取元素。
  • LinkedTransferQueue:一个由链表结构组成的无界阻塞队列。与SynchronousQueue类似,还含有非阻塞方法。
  • LinkedBlockingDeque:一个由链表结构组成的双向阻塞队列。

ThreadFactory 创建线程的工厂

线程池创建线程时调用的工厂方法,通过此方法可以设置线程的优先级、线程命名规则以及线程类型(用户线程还是守护线程)等。一般情况下使用默认的,即Executors类的静态方法defaultThreadFactory(),也可以自定义。

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class Test {
    public static void main(String[] args) {
        // 创建线程工厂
        ThreadFactory threadFactory = new ThreadFactory() {
            @Override
            public Thread newThread(Runnable runnable) {
                // 创建线程池中的线程
                Thread thread = new Thread(runnable);
                // 设置线程名称
                thread.setName("Thread-" + runnable.hashCode());
                // 设置线程优先级(最大值:10)
                thread.setPriority(Thread.MAX_PRIORITY);
                //......
                return thread;
            }
        };
        // 创建线程池
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                5,
                10,
                0L,
                TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<Runnable>(10),
                threadFactory
        );
        try{
            threadPoolExecutor.submit(new Runnable() {
                @Override
                public void run() {
                    Thread thread = Thread.currentThread();
                    System.out.println(String.format("线程:%s,线程优先级:%d",thread.getName(), thread.getPriority()));
                }
            });
        }catch (Exception e) {
        } finally {
            threadPoolExecutor.shutdown();
        }
    }
}

Executors.defaultThreadFactory()

RejectedExecutionHandler

拒绝策略。当线程池的任务超出线程池队列可以存储的最大值之后,执行的策略。

  • AbortPolicy策略:直接抛出异常,阻止系统正常工作。(线程池的默认策略)。
  • DiscardOldestPolicy策略:丢弃任务队列中最早添加的任务,并尝试提交当前任务。
  • CallerRunsPolicy策略:调用主线程执行被拒绝的任务,这提供了一种简单的反馈控制机制,将降低新任务的提交速度。
  • DiscardPolicy策略:忽略并抛弃当前任务。

new一个线程池

责任编辑:姜华 来源: 今日头条
相关推荐

2010-12-23 15:45:31

程序员编程

2011-06-09 13:26:27

编程程序员

2013-04-22 11:13:06

程序员编程误区

2011-06-07 10:28:51

程序员

2014-11-07 16:57:21

程序员

2019-11-27 18:43:36

程序员编程语言软件

2013-07-09 15:04:17

程序员编程

2010-08-10 14:45:57

FlexBlazeDS

2009-02-24 09:28:29

2009-08-26 10:06:40

七夕程序员

2018-08-06 10:25:07

Linux命令程序员

2022-03-09 07:35:24

线程池线程参数

2016-11-23 07:33:54

编程语言GitHub程序员

2020-11-25 10:40:58

程序员技能开发者

2009-08-31 16:28:35

程序开发语言

2019-01-30 14:14:16

LinuxUNIX操作系统

2020-12-10 08:24:40

线程池线程方法

2024-04-24 09:02:58

线程池面试锁升级

2023-09-12 11:25:15

2022-10-28 10:23:27

Java多线程底层
点赞
收藏

51CTO技术栈公众号