线程池的七个配置参数,很细!!!
ThreadPoolExecutor 有参构造方法提供了七个参数,根据这7个对应参数可以按照业务需求自定义合适的线程池,ThreadPoolExecutor 自定义线程池Demo 可以参考 ==>,具体的参数含义与作用请往下看。
以ThreadPoolExecutor为例
ThreadPoolExecutor 有参构造方法提供了七个参数,根据这7个对应参数可以按照业务需求自定义合适的线程池,ThreadPoolExecutor 自定义线程池Demo 可以参考 ==> JAVA线程池创建的几种方式,有案例很细!!!(持续更新中)_骑电动车的小黄的博客-CSDN博客,具体的参数含义与作用请往下看。
1、corePoolSize(核心线程数)
corePoolSize表示核心线程数,核心线程数是指线程池中始终保持着活动的线程数量,可以这么理解,就算线程池中没有任务执行,线程为空闲状态也不会被回收。
但是也有可以被回收的情况,例如我们设置线程池中 allowCoreThreadTimeOut 为 true 那么核心线程数也会因为超过一定的阈值而被回收,设置 allowCoreThreadTimeOut 的案例如下
public class PoolTest {
public static void main(String[] args) {
// 创建一个阻塞队列,用于存放等待执行的任务
BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>(10);
// 创建自定义的线程池,设置核心线程数、最大线程数、等待时间、时间单位、任务队列等参数
ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 1, TimeUnit.MINUTES, queue);
// 提交任务给线程池,使用 execute() 方法提交
for (int i = 0; i < 10; i++) {
Runnable task = new MyTask(i);
executor.execute(task);
}
// 设置为 true 那么一些空闲的核心线程可能会在超过一分钟之后被回收掉
executor.allowCoreThreadTimeOut(true);
// 关闭线程池
executor.shutdown();
}
}
class MyTask implements Runnable {
private final int taskId;
public MyTask(int taskId) {
this.taskId = taskId;
}
@SneakyThrows
@Override
public void run() {
Thread.sleep(2000);
System.out.println("Task ID : " + taskId + " 执行 " + Thread.currentThread().getName());
}
}
2、keepAliveTime(空闲的线程存活时间)
它表示当线程处于空闲状态的时候或没有任务执行时,线程可额外存活的时间,如果这段额外的时间没有需要处理的任务,那么超过这个时间空闲的线程就会被终止并从线程池中移除。例如上面的例子,设置的是1分钟超时时间(可以自己设置),空闲时间超过一分钟线程就会被回收掉。
3、unit(时间单位)
是用于表示线程池中时间单位的枚举类型,提供了一个枚举类 java.util.concurrent.TimeUnit 可以配置枚举类中任意一种例如 TimeUnit.SECONDS 秒,TimeUnit.MINUTES 分钟,TimeUnit.HOURS 小时,TimeUnit.DAYS 天 等,配合 keepAliveTime(空闲的线程存活时间)进行使用。
4、workQueue(任务队列)
用于存储线程池中待执行任务的阻塞队列,通常下线程池中任务数量超过了 corePoolSize(核心线程数)时,那么新提交的任务就会被放至 workQueue(任务队列)当中,例如上面案例设置的任务队列大小为10,核心线程数为 5,当线程池正在执行的任务超过5的时候就会把新提交的任务暂放至任务队列当中,任务队列当中等待的任务最多为10个。
线程池的工作队列当中可以是不同的阻塞队列,案例中使用的是 LinkedBlockingQueue,常用的阻塞队列有:
- LinkedBlockingQueue:一个基于链表结构的可选有界阻塞队列,按照先进先出的顺序进行任务调度。如果不指定容量大小,则默认为 Integer.MAX_VALUE。
- PriorityBlockingQueue:一个基于优先级的无界阻塞队列,可以按照自定义的顺序执行任务。
- SynchronousQueue:一个不存储元素的阻塞队列,每个插入操作必须等待另一个线程的移除操作。在这种队列中,每个插入操作都会阻塞,直到有其他线程来获取数据。
- ArrayBlockingQueue:一个基于数组结构的有界阻塞队列,按照先进先出(FIFO)的顺序进行任务调度。
5、maximumPoolSize(最大线程数)
线程池中允许的最大线程数量,包括核心线程和额外创建的临时线程数量。
在向线程池中提交任务的时,假如当前的任务数量超过了corePoolSize(核心线程数),同时workQueue(任务队列)也满了,那么就会根据需要来创建corePoolSize(核心线程数)之外的临时线程数,但 corePoolSize(核心线程数)和 临时线程数总数不能超过maximumPoolSize(最大线程数)。
6、handler(拒绝策略)
用来处理线程池中的workQueue(任务队列)已满、并且线程池中的线程数已达到maximumPoolSize(最大线程数)时的情况,线程池会根据定义的拒绝策略来处理这些任务。
内置的拒绝策略有以下几种:
- AbortPolicy:直接抛出 RejectedExecutionException 异常,表示无法接受新任务,没有配置拒绝策略,默认为该策略。
- CallerRunsPolicy:将任务回退到调用者所在线程中执行,也就是由调用 execute 方法的线程来执行该任务。
- CallerRunsPolicy:将任务回退到调用者所在线程中执行,也就是由调用 execute 方法的线程来执行该任务。
- DiscardPolicy:直接丢弃无法处理的任务,不做任何处理。
- DiscardOldestPolicy:丢弃添加到工作队列最早的任务,并尝试重新提交当前任务。
7、threadFactory(创建线程工厂)
用来创建线程工厂的类,在线程池中需要创建新线程时使用 threadFactory(创建线程工厂) 进行创建线程对象,可以通过自定义 threadFactory(创建线程工厂)对线程进行个性化配置和定制,例如设置线程的名称、优先级等,可以更好的跟踪和管理线程池中的线程,例如以下案例给线程池中线程进行命名。
public class PoolTest {
public static void main(String[] args) {
int corePoolSize = 5;
int maximumPoolSize = 10;
long keepAliveTime = 1;
TimeUnit unit = TimeUnit.MINUTES;
BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>();
ThreadFactory threadFactory = new MyThreadFactory(); // 自定义的ThreadFactory
ThreadPoolExecutor executor = new ThreadPoolExecutor(
corePoolSize,
maximumPoolSize,
keepAliveTime,
unit,
workQueue,
threadFactory
);
// csdn 骑电动车的小黄
for (int i = 0; i < 10; i++) {
// 提交任务到线程池
executor.execute(new Runnable() {
@Override
public void run() {
// 任务逻辑代码
System.out.println("开始执行任务 线程的自定义名称为:" + Thread.currentThread().getName());
}
});
}
// 关闭线程池...
executor.shutdown();
}
}
class MyThreadFactory implements ThreadFactory {
private static final String THREAD_NAME_PREFIX = "这是一个线程自定义名称-";
private int counter = 1;
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r);
thread.setName(THREAD_NAME_PREFIX + counter);
thread.setPriority(Thread.NORM_PRIORITY);
thread.setDaemon(false);
counter++;
return thread;
}
}
执行结果:
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)