从0到1深入理解JAVA线程池
2023-04-18 15:03:09 时间
Executors实现关系图
线程池核心思想
线程是由工作线程、缓存队列组成的一个协作流程,缓存队列一直接收数据,工作线程一直处在从队列中取数据、处理数据。
JDK1.8线程池剖析
那么缓存队列多大?工作线程多少?不够该怎么办?这个是非常值得研究,下面我们来看看java内置的集中线程池是怎么样对这几个参数进行配置的。
1、ThreadPoolExecutor
newFixedThreadPool(int nThreads):工作线程数和最大线程数相同,也就是工作线程一直都是一样的线程池,同时这个缓存队列是非常的大size=Integer.MAX_VALUE
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
/**
* Creates a {@code LinkedBlockingQueue} with a capacity of
* {@link Integer#MAX_VALUE}.
*/
public LinkedBlockingQueue() {
this(Integer.MAX_VALUE);
}
newSingleThreadExecutor():创建一个只有一个工作线程的线程池
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
newCachedThreadPool():初始化工作线程数为0,最大线程数为Integer.MAX_VALUE的线程池
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
2、ForkJoinPool
newWorkStealingPool(int parallelism):将一个大任务拆成parallelism小任务进行执行
public static ExecutorService newWorkStealingPool(int parallelism) {
return new ForkJoinPool
(parallelism,
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
null, true);
}
3、ScheduledThreadPoolExecutor
newSingleThreadScheduledExecutor():初始一个工作线程的定时线程池,最大线数为Integer.MAX_VALUE的线程池
public ScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
new DelayedWorkQueue());
}
结束语
从上面常用的线程池来看的,jdk默认的线程池要么就是缓存队列特别大,要么就是最大线程数特别大,这种会导致一些极端情况,因为线程和缓存都是要消耗资源的,所以一般我们在实践过程中都会自己新建一个线程池来合理设置线程数和缓存队列大小,可参考:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.acc = System.getSecurityManager() == null ?
null :
AccessController.getContext();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
相关文章
- 硬核 | 基于ASM实现Java类与接口的动态代理
- 作为一名 Java 开发人员,如何在数十年中保持快乐和相关性
- 腾讯会议部分功能开始收费、Windows 10将于明年2月永久禁用IE11、华为前三季研发费用超1100亿 | T资讯
- 甲骨文加仓Java,数据库被榨干了?
- 一次单元测试优化的过程总结
- Java 实现100 万+并发,搞懂这些,骚操作!
- Java性能优化的七个方向
- 不懂优雅停机,搞挂了线上服务该咋办?
- 如何在 Ubuntu Linux 中正确地设置 JAVA_HOME 变量
- 如何在 Linux 上手动安装 Java
- 如何在 Ubuntu 中运行 Java 程序
- HarmonyOS使用Java获取位置信息
- 如何在 Fedora Linux 上安装 Java
- HarmonyOS基于Java开发的服务卡片
- 《漫谈 MQ》设计 MQ 的 3 个难点
- Java开发日常
- 手把手教你提交Jar包到Maven公共仓库 | 萌新写开源02
- 一次完整的JVM堆外内存泄漏故障排查记录
- elasticsearch之自定义Java代码的安全策略管理
- Java中的受检异常