线程池
线程池
1、线程池的7个参数
corePoolSize, 核心线程数,当新的任务到来时,如果当前核心线程的数量没有>设置的值就新建一个线程执行该任务;否则,就将新任务放入工作队列/等待队列中maximumPoolSize,线程池的最大线程数,当新任务到来时,如果当前线程数量 >= maximumPoolSize,执行拒绝策略handler;否则,- 将任务加入工作队列,
当前线程数量 == corePoolSize && workQueue 未满 - 或者新建核心线程执行,
当前线程数量 < corePoolSize - 或者新建工作线程执行,
当前线程数量 == corePoolSize && workQueue 以满
- 将任务加入工作队列,
keepAliveTime, 保活时间,一个线程空闲的最长时间,long型,单位由unit决定。- 默认只会对非核心线程起作用,可以通过
threadPoolExecutor.allowCoreThreadTimeOut(true);设置为对核心线程起作用,此时,必须满足keepAliveTime>0,因为核心线程必须存活时间大于0;否则会抛出IllegalArgumentException("Core threads must have nonzero keep alive times");异常
- 默认只会对非核心线程起作用,可以通过
unit, 保活时间的单位,取值从TimeUnit这个枚举类中取值workQueue, 当新的任务到来时,如果,当前线程数量 == corePoolSize && workQueue 未满,将任务加入工作队列threadFactory, 线程工厂,可以使用自定义的线程工程,自定义线程名字的前缀,方便排查问题handler, 拒绝策略,当当前的线程数量 == maximumPoolSize && workQueue 已满,执行拒绝策略ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。ThreadPoolExecutor.DiscardPolicy:丢弃任务,但是不抛出异常。ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新提交被拒绝的任务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,并且工作队列已满,所以抛出异常
本文来自博客园,作者:永恒&,转载请注明原文链接:https://www.cnblogs.com/Sun-yuan/p/17441794.html

浙公网安备 33010602011771号