文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

你能说下线程池有几个参数吗,分别代表什么?

2024-11-30 00:26

关注

先说下线程池中几个参数的含义:

ThreadPoolExecutor初始化的时候一般会有7个参数:

ThreadPoolExecutor的工作原理:

往线程池中提交第一个任务,底层会创建第一个核心线程,将线程和任务封装为一个woker对象放入set集合中,接下来每提交一个的任务都会对应创建一个核心线程和这个任务封装的woker对象放入set集合中,直到核心线程数达到corePoolSize,再次提交到线程池的任务会被放到阻塞队列排队执行,如果放队列的过程中,队列满了,就会创建一个非核心线程和这个任务封装为woker对象放入set集合中,如果最终已经达到最大线程数maximumPoolSize,就采用拒绝策略。如果放入队列过程中发现工作线程数位0,则创建一个空任务的Worker。

再来看下线程池的标识:

线程池的标识有两层含义:

底层是用按位分隔的设计方式将一个int类型的变量的32位进行分割,用高3位表示线程状态,低29位表示线程数量。

线程池的5个状态:RUNNING= -1,正常运行状态 SHUTDOWN= 0, 表示不接受新任务,只把队列中的任务处理完结束。STOP= 1,表示不接受新任务,也不处理队列中的任务了。IDYING= 2,非正常状态 TERMINATED = 3,死亡状态

按位分割的好处就是用一个变量表示两个状态,在修改的时候可以利用cas保证原子性。

Worker对象创建逻辑是由addWorker方法实现的。

addWorker方法逻辑:

1.retry;双层循环

第一层循环主要判断:如果当前线程池状态为RUNNING就放行, 如果状态为SHUTDOWN就必须满足传进来的新任务为null,队列中有待处理的任务才会放行(因为SHUTDOWN状态下不接受新任务,只处理队列中的任务);如果状态为STOP,IDYING,TERMINATED就一定不放行;

第二层循环主要是判断线程数,如果是创建核心线程,就判断是否达到corePoolSize,否则就判断是否达到maximumPoolSize,如果达到就返回fasle不放行。

如果未达到就放行,放行的时候会利用cas更新线程数,如果更新成功则两层循环结束,继续下面的逻辑。

因为是cas操作,多线程的情况下可能会有更新线程数量失败的情况,在这种情况下要判断之前获取的线程池状态和现在的线程池状态是否一致,如果不一致那就要重新判断状态,从而进入到外层循环的下一轮循环,如果一致就只需要进入到内层循环的下一轮循环。

2.创建Worker对象

接下来就是创建Worker(任务),Worker类继承aqs,封装了线程工厂,初始化的时候会利用工厂创建一个线程,并且和传进来的任务封装为worker对象。

获取线程池全局锁(reentrylock作为线程池全局锁),进行上锁操作

将创建的worker加入workers集合,workers是一个hashset集合。

放入集合后就可以解锁了

worker创建完成了,接下来就是启动线程,启动线程后就会执行worker中的run方法

3.run方法流程

这个方法中主要的逻辑是这段代码

while (task != null || (task = getTask()) != null){
  逻辑
}

task是worker对象封装的任务。如果当前worker对象上没有任务就调用getTask去阻塞队列拿任务,如果能拿到就处理任务。如果getTask返回null就跳出循环,进入processWorkerExit方法。

我们知道线程池中的任务是放在队列中的,ThreadPoolExecutor中的队列一般默认是阻塞队列LinkedBlockingQueue,

getTask()方法会在这个队列中拿任务,如果有任务就直接返回任务,如果此时队列中无任务,当前线程会阻塞等待任务到来。

但是如果设置了非核心线程最大空闲时间keepAliveTime,代表非核心线程的worker对象中的线程在拿任务的时候不会用take方法,而是用poll,poll这个方法可以设置阻塞等待时间为keepAliveTime。当超过这个时间还没有任务就会返回null。

4.processWorkerExit方法逻辑

上一步中如果没有获取到任务并且返回了null就会进入processWorkerExit方法。这个方法的逻辑就是把当前非核心线程的worker从workers集合中移除。最后会做一个判断:如果此时没有任何工作线程了,并且阻塞队列中还有任务,那就再创建一个不带任务的非核心线程worker。保证有线程去处理队列中的任务。

拒绝策略:

其他了解:

线程监控API:
 while (true) {
 System.out.println();
 int queueSize = tpe.getQueue().size();
 System.out.println("当前排队线程数:" + queueSize);
 int activeCount = tpe.getActiveCount();
 System.out.println("当前活动线程数:" + activeCount);
 long completedTaskCount = tpe.getCompletedTaskCount();
 System.out.println("执行完成线程数:" + completedTaskCount);
 long taskCount = tpe.getTaskCount();
 System.out.println("总线程数:" + taskCount);
 Thread.sleep(3000);
 }


来源:码农本农内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯