线程池-基础篇

常用线程池

Executors提供四种线程池:

1.newCachedThreadPool :缓存线程池,如果线程池长度超过处理需要,可回收空闲线程,若无可回收,则新建线程。

2.newFixedThreadPool : 定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。

3.newScheduledThreadPool : 计划线程池,支持定时及周期性任务执行。
4.newSingleThreadExecutor :单线程线程池,用唯一的线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行

核心参数

corePoolSize:核心线程数

线程池维护的最小线程数量,核心线程创建后不会被回收(注意:设置allowCoreThreadTimeout=true后,空闲的核心线程超过存活时间也会被回收)
大于核心线程数的线程,在空闲时间超过keepAliveTime后会被回收
线程池刚创建时,里面没有一个线程,当调用execute()方法添加一个任务时,如果正在运行的线程数量小于corePoolSize,则马上创建新线程并运行这个任务。

maximumPoolSize:最大线程数

线程池允许创建的最大线程数量
当添加一个任务时,核心线程数已满,线程池还没达到最大线程数,并且没有空闲线程,工作队列已满的情况下,创建一个新线程并执行。

keepAliveTime:空闲线程存活时间

当一个可被回收的线程空闲时间大于keepAliveTime,就会被回收。
可被回收的线程:
1.设置allowCoreThread=true的线程。
2.大于核心线程数的线程(非核心线程)。

unit:时间单位

keepAliveTime的时间单位

workQueue:工作队列

存放待执行任务的队列:当提交的任务数超过核心线程数大小后,再提交的任务就存放在工作队列,任务调度时再从队列中取出任务。它仅仅用来存放被execute()方法提交的Runnable任务。工作队列实现了BlockingQueue接口。
JDK默认的工作队列有五种:
1.ArrayBlockingQueue 数组型阻塞队列: 数组结构,初始化时传入大小,有界,FIFO,使用一个重入锁,默认使用非公平锁,入队和出队共用一个锁,互斥。
2.LinkedBlockingQueue 链表型阻塞队列: 链表结构,默认初始化大小为Integer.MAX VALUE,有界(近似无解),FIFO,使用两重入锁分别控制元素的入队和出队,用Condition进行线程间的唤醒和等待。
3.SynchronousQueue 同步队列: 容量为0,添加任务必须等待取出任务,这个队列相当于通道,不存储元素.
4.PriorityBlockingQueue 优先阻塞队列: 无界,默认采用元素自然顺序升序排列。
5.DelayQueue 延时队列: 无界,元素有过期时间,过期的元素才能被取出。

threadFactory:线程工厂

创建线程的工厂,可设定线程名、线程编号等。

handler:拒绝策略

当线程池线程数已满,并且工作队列达到限制,新提交的任务使用拒绝策略处理。可以自定义拒绝策略,拒绝策略需要实现RejectedExecutionHandler接口。

还有几个重要成员变量:

ThreadPoolExecutor有几个重要的成员变量:allowCoreThreadTimeOut(是否允许核心线程超时退出)、poolSize(线程池中当前线程的数量)。

注意还有一个largestPoolSize,记录了曾经出现的最大线程个数。因为setMaximumPoolSize()可以改变最大线程数。

拒绝策略

1.ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
2.ThreadPoolExecutor.DiscardPolicy:丢弃任务,但是不抛出异常。
3.ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新提交被拒绝的任务
4.ThreadPoolExecutor.CallerRunsPolicy:由调用线程(提交任务的线程)处理该任务

posted @ 2023-11-22 23:21  轻寒  阅读(6)  评论(0编辑  收藏  举报