JDK线程池解析
脑子一直没有一个体系,今天有时间来总结一下
Java提供了一个Executors工厂类,它提供了一些静态方法来创建不同类型的线程池:
newFixedThreadPool:返回固定长度的线程池,线程池中的线程数量是固定的。
阿里规范:使用Executors创建的线程池通常不建议用于生产环境,因为它们的默认配置可能不适合所有的应用场景。例如,newCachedThreadPool()可能会创建大量的线程,导致资源耗尽。
@Test
public void testThread() throws ExecutionException, InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(10);
Future<Integer> future = executorService.submit(() -> {
System.out.println("开始线程工作");
return 10;
});
System.out.println(future.get());
}
解析:Executors是一个工厂,里面封装了不同类型的线程池,帮我们做了创建了ThreadPoolExecutor:
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
ThreadPoolExecutor是什么?看源码是继承了AbstractExecutorService
这个抽象的AbstractExecutorService是实现了ExecutorService
所以ThreadPoolExecutor是间接实现了ExecutorService
那ExecutorService呢?这个接口是继承了顶层接口Executor,顶层接口只是定义了核心功能,而ExecutorService这个接口是对顶层接口进行了扩展,也是一个接口
ThreadPoolExecutor extends AbstractExecutorService
public abstract class AbstractExecutorService implements ExecutorService
public interface ExecutorService extends Executor
public interface Executor {
/**
* Executes the given command at some time in the future. The command
* may execute in a new thread, in a pooled thread, or in the calling
* thread, at the discretion of the {@code Executor} implementation.
*
* @param command the runnable task
* @throws RejectedExecutionException if this task cannot be
* accepted for execution
* @throws NullPointerException if command is null
*/
void execute(Runnable command);
}
总结:ThreadPoolExecutor是ThreadPoolExecutor的一个具体实现类,提供了一个能够管理和执行异步任务的线程池。ThreadPoolExecutor允许你配置线程池的大小、任务的执行策略、任务队列以及任务拒绝策略等
有点乱,来跟着我思路捋一遍:首先Executor是一个顶层接口,然后它下面的ExecutorService接口继承了该接口,对其功能进行了扩展,然后抽象类AbstractExecutorService实现了该接口,然后ThreadPoolExecutor继承了该抽象类,相当于间接实现了ExecutorService
思考:源码中为什么会有public abstract class AbstractExecutorService implements ExecutorService呢?直接让ThreadPoolExecutor实现ExecutorService接口不行吗?
其实ThreadPoolExecutor就是一个执行器,它还有其他同类型的执行器(ScheduledThreadPoolExecutor、ForkJoinPool),所以abstractExecutorService作为一个中间层,使得ThreadPoolExecutor和其他执行器服务实现能够更加专注于它们独特的功能,同时保持代码的清晰和可维护性。
Spring提供的线程池
@Bean(name = "taskExecutor")
public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
pool.setKeepAliveSeconds(keepAliveSeconds);
//核心线程池数
pool.setCorePoolSize(corePoolSize);
// 最大线程
pool.setMaxPoolSize(maxPoolSize);
//队列容量
pool.setQueueCapacity(queueCapacity);
//队列满,线程被拒绝执行策略
pool.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
return pool;
}
公司中的使用,自定义的线程池参数
threadPoolTaskExecutor是实现了TaskExecutor接口,与ThreadPoolExecutor类型都是一个执行器
使用类似:使用execute或者submit执行,异步配合:
CompletableFuture.allOf 方法用于同步等待一组异步操作的完成,但它本身并不返回这些操作的结果
join 来获取每个 CompletableFuture 对象的结果
//同步等待一组异步操作的完成
CompletableFuture<Void> result1 = CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()]));
//来获取每个 `CompletableFuture` 对象的结果
CompletableFuture<List<FilterData>> listCompletableFuture1 = result1.thenApply(v -> futures.stream().map(CompletableFuture::join).collect(Collectors.toList()));