线程池的原理(fixed线程池)

线程池由两个核心数据结构组成:

1)线程集合(workers):存放执行任务的线程,是一个HashSet;

2)任务等待队列(workQueue):存放等待线程池调度执行的任务,是一个阻塞式队列BlockingQueue;
线程池有几个核心参数:
在这里插入图片描述

任务执行流程

1)线程池中线程数量小于corePoolSize,此时任务不会进等待队列,线程池直接创建一个线程Worker执行提交的任务;
2)线程池中线程数量不小于corePoolSize并且等待队列未满,任务直接添加到等待队列,等待线程池调度执行;
3)线程池中线程数量不小于corePoolSize但是等待队列已满且线程数量小于maximumPoolSize,线程池会进行扩容新创建一个线程Worker执行提交的任务,新创建的Worker会被添加到线程集合workers中;
4)等待队列已满并且线程数量已达到maximumPoolSize,这种情况下线程池无法继续执行任务会拒绝任务,执行一个指定的拒接策略。
5)线程池已关闭,拒绝任务,执行一个指定的拒接策略。

注:线程创建之后,会不停从等待队列workQueue中拉取任务,workQueue是一个线程安全的阻塞队列,所以不存在线程安全问题,拉取到任务之后,执行任务逻辑。拉取任务时有两种情况:

1)线程池设置了keepAliveTime参数,并且此时线程池中的线程数量超过核心数量corePoolSize,从队列中拉取任务时会设置keepAliveTime为超时时间,超过这个时间之后,该线程不再等待任务,直接跑完run方法体,线程被回收;

2)否则线程会无限等待任务队列直到有任务到来。

拒绝策略(RejectedExecutionHandler)

1)调用线程执行(CallerRunsPolicy),任务被线程池拒绝后,任务会被调用线程执行;
2)终止执行(AbortPolicy),任务被拒绝时,抛出RejectedExecutionException异常报错
3)丢弃任务(DiscardPolicy),任务被直接丢弃,不会抛异常报错;

4)丢失老任务(DiscardOldestPolicy),把等待队列中最老的任务删除,删除后重新提交当前任务。

关闭线程池

关闭线程池时有两个关键步骤:

1)修改线程池状态到SHUTDOWN,这时新提交到线程池的任务都会被直接拒绝(正在执行的线程不会被停止);

2)中断线程池中的所有线程(STOP),中断任务执行回收线程集合中所有线程。

线程池的状态

RUNNING, 运行状态,值也是最小的,刚创建的线程池就是此状态。
SHUTDOWN,停工状态,不再接收新任务,已经接收的会继续执行
STOP,停止状态,不再接收新任务,已经接收正在执行的,也会中断
清空状态,所有任务都停止了,工作的线程也全部结束了 TERMINATED,
终止状态,线程池已销毁

线程池的线程是如何做到复用的。

线程池中的线程在循环中尝试取任务执行,这一步会被阻塞,如果设置了allowCoreThreadTimeOut为true,则线程池中的所有线程都会在keepAliveTime时间超时后还未取到任务而退出。或者线程池已经STOP,那么所有线程都会被中断,然后退出

线程池是如何做到高效并发的

看整个线程池的工作流程,有以下几个需要特别关注的并发点.
①: 线程池状态和工作线程数量的变更。这个由一个AtomicInteger变量 ctl来解决原子性问题。
②: 向工作Worker容器workers中添加新的Worker的时候。这个线程池本身已经加锁了。
③: 工作线程Worker从等待队列中取任务的时候。这个由工作队列本身来保证线程安全,比如LinkedBlockingQueue等。(所以声明一个线程池可以在成员变量中声明(静态) 如果在方法中声明 每一个线程都会创建一个线程池对象 浪费资源(单例对象情况下)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Hutool是一个Java工具类库,它提供了丰富的功能来简化Java开发过程。Hutool中的线程池模块提供了一个方便的方式来管理和使用线程池。 要使用Hutool的线程池模块,首先需要引入Hutool的依赖。你可以在你的项目中的pom.xml文件中添加以下依赖项: ```xml <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.7.7</version> </dependency> ``` 然后,你可以通过以下代码创建一个线程池并执行任务: ```java import cn.hutool.core.thread.ThreadFactoryBuilder; import cn.hutool.core.util.RandomUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.core.thread.ThreadUtil; import java.util.concurrent.ExecutorService; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; public class ThreadPoolExample { public static void main(String[] args) { // 创建固定线程数的线程池 ExecutorService fixedThreadPool = ThreadUtil.newExecutor(5); // 提交任务给线程池执行 fixedThreadPool.execute(() -> { System.out.println("Thread Name: " + Thread.currentThread().getName()); }); // 创建调度线程池 ScheduledExecutorService scheduledThreadPool = ThreadUtil.newScheduledExecutor(2); // 延迟执行任务 scheduledThreadPool.schedule(() -> { System.out.println("Single Scheduled Thread Name: " + Thread.currentThread().getName()); }, 1, TimeUnit.SECONDS); // 定期执行任务 scheduledThreadPool.scheduleAtFixedRate(() -> { System.out.println("Fixed-Rate Scheduled Thread Name: " + Thread.currentThread().getName()); }, 0, 2, TimeUnit.SECONDS); } } ``` 这是一个简单的使用Hutool线程池的示例代码。你可以根据自己的需求来配置线程池的大小和其他属性,然后提交任务给线程池执行。同时,Hutool还提供了其他功能来处理线程池相关的操作,比如动态修改线程池大小、等待线程池中的任务执行完毕等。你可以查阅Hutool的官方文档来了解更多关于线程池模块的使用方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值