当前位置:首页 > 数码 > 揭秘线程池的七大参数-深化了解其性能和作用 (线程线程池)

揭秘线程池的七大参数-深化了解其性能和作用 (线程线程池)

admin7个月前 (05-01)数码41

问:可以说一下线程池吗?

关于线程池的疑问,大少数面试官会问线程池的几个参数的含意,当天就间接聊一聊线程池ThreadPoolExecutor。

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

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方法逻辑:

retry;双层循环

第一层循环关键判别:假设以后线程池形态为RUNNING就放行,假设形态为SHUTDOWN就必定满足传出去的新义务为null,队列中有待处置的义务才会放行(由于SHUTDOWN形态下不接受新义务,只处置队列中的义务);假设形态为STOP,IDYING,TERMINATED就必定不放行;

第二层循环关键是判别线程数,假设是创立外围线程,就判别能否到达corePoolSize,否则就判别能否到达maximumPoolSize,假设到达就前往fasle不放行。

假设未到达就放行,放行的时刻会应用cas更新线程数,假设更新成功则两层循环完毕,继续上方的逻辑。

由于是cas操作,多线程的状况下或者会有更新线程数量失败的状况,在这种状况下要判别之前失掉的线程池形态和如今的线程池形态能否分歧,假设不分歧那就要从新判别形态,从而进入到外层循环的下一轮循环,假设分歧就只有要进入到内层循环的下一轮循环。

创立Worker对象

接上去就是创立Worker(义务),Worker类承袭aqs,封装了线程工厂,初始化的时刻会应用工厂创立一个线程,并且和传出去的义务封装为worker对象。

失掉线程池全局锁(reentrylock作为线程池全局锁),启动上锁操作

将创立的worker添加workers汇合,workers是一个hashset汇合。

放入汇合后就可以解锁了

worker创立成功了,接上去就是启动线程,启动线程后就会口头worker中的run方法

run方法流程

这个方法中关键的逻辑是这段代码

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

task是worker对象封装的义务。假设以后worker对象上没有义务就调用getTask去阻塞队列拿义务,假设能拿到就处置义务。假设getTask前往null就跳出循环,进入processWorkerExit方法。

咱们知道线程池中的义务是放在队列中的,ThreadPoolExecutor中的队列普通自动是阻塞队列LinkedBlockingQueue,

getTask()方法会在这个队列中拿义务,假设有义务就间接前往义务,假设此时队列中无义务,以后线程会阻塞期待义务来到。

但是假设设置了非外围线程最大闲暇期间keepAliveTime,代表非外围线程的worker对象中的线程在拿义务的时刻不会用take方法,而是用poll,poll这个方法可以设置阻塞期待期间为keepAliveTime。当超越这个期间还没有义务就会前往null。

上一步中假设没有失掉到义务并且前往了null就会进入processWorkerExit方法。这个方法的逻辑就是把以后非外围线程的worker从workers汇合中移除。最后会做一个判别:假设此时没有任何上班线程了,并且阻塞队列中还有义务,那就再创立一个不带义务的非外围线程worker。保障有线程去处置队列中的义务。

拒绝战略:

其余了解:

线程监控API:while(true){System.out.println();intqueueSize=tpe.getQueue().size();System.out.println("以后排队线程数:"+queueSize);intactiveCount=tpe.getActiveCount();System.out.println("以后优惠线程数:"+activeCount);longcompletedTaskCount=tpe.getCompletedTaskCount();System.out.println("口头成功线程数:"+completedTaskCount);longtaskCount=tpe.getTaskCount();System.out.println("总线程数:"+taskCount);Thread.sleep(3000);}

线程池七大核心参数

线程线程池

线程池七大核心参数如下所示:

一、corePoolSize 线程池核心线程大小

线程池中会维护一个最小的线程数量,即使这些线程处理空闲状态,他们也不会被销毁,除非设置了allowCoreThreadTimeOut。这里的最小线程数量即是corePoolSize。任务提交到线程池后,首先会检查当前线程数是否达到了corePoolSize,如果没有达到的话,则会创建一个新线程来处理这个任务。

二、maximumPoolSize 线程池最大线程数量

当前线程数达到corePoolSize后,如果继续有任务被提交到线程池,会将任务缓存到工作队列(后面会介绍)中。如果队列也已满,则会去创建一个新线程来出来这个处理。线程池不会无限制的去创建新线程,它会有一个最大线程数量的限制,这个数量即由maximunPoolSize指定。

三、keepAliveTime 空闲线程存活时间

一个线程如果处于空闲状态,并且当前的线程数量大于corePoolSize,那么在指定时间后,这个空闲线程会被销毁,这里的指定时间由keepAliveTime来设定。

四、unit 空闲线程存活时间单位

空闲线程存活时间单位是keepAliveTime的计量单位。

五、workQueue 工作队列

新任务被提交后,会先进入到此工作队列中,任务调度时再从队列中取出任务。

六、threadFactory 线程工厂

创建一个新线程时使用的工厂,可以用来设定线程名、是否为daemon线程等等。

七、handler 拒绝策略

当工作队列中的任务已到达最大限制,并且线程池中的线程数量也达到最大限制,这时如果有新任务提交进来,该如何处理呢。这里的拒绝策略,就是解决这个问题的。

线程池的优势

1、线程和任务分离,提升线程重用性;

2、控制线程并发数量,降低服务器压力,统一管理所有线程;

3、提升系统响应速度,假如创建线程用的时间为T1,执行任务用的时间为T2,销毁线程用的时间为T3,那么使用线程池就免去了T1和T3的时间。

线程池七大核心参数

线程池七大核心参数是corePoolSize、maximumPoolSize、KeepAliveTime、unit、workQueue、threadFactory、handler。

1、corePoolSize核心线程数

线程池中会维护一个最小的线程数量,即使这些线程处理空闲状态,它们也不会被销毁,除非设置了alowCoreThreadTimeOut,这里的最小线程数量即是corePoolSize,任务提交到线程池后,首先会检查当前线程数是否达到了corePoolSize,如果没有达到的话,则会创建个新线程来处理这个任务。

2、maximumPoolSize最大线程数

当前线程数达到corePoolSize后,如果继续有任务被提交到线程池,会将任务缓存到任务队列中。如果队列也已满,则会去创建一个新线程来出来这个处理。线程池不会无限制的去创建新线程,它会有一个最大线程数量的限制,这个数量即由maximunPoolSize指定。

3、KeepAliveTime空闲线程存活时间

一个线程如果处于空闲状态,并且当前的线程数量大于corePolSize,那么在指定时间后,这个空闲线程会被销毁,这里的指定时间由keepAliveTime来设定。

4、unit空闲线程存活时间单位

keepAliveTime的计量单位。

5、workQueue任务队列

新任务被提交后,会先进入到此任务队列中,任务调度时再从队列中取出任务。

6、threadFactory线程工厂

创建一个新线程时使用的工厂,可以用来设定线程名、是否为daemon线程等等。

7、handler拒绝策略

当工作队列中的任务已到达最大限制,并且线程池中的线程数量也达到最大限制,这时如果有新任务提交进来,该如何处理呢?这里的拒绝策略,就是解决这个问题的。

线程池的模式介绍:

1、半同步/半异步模式又称为生产者消费者模式,是比较常见的实现方式,比较简单。分为同步层、队列层、异步层三层。同步层的主线程处理工作任务并存入工作队列,工作线程从工作队列取出任务进行处理,如果工作队列为空,则取不到任务的工作线程进入挂起状态。由于线程间有数据通信,因此不适于大数据量交换的场合。

2、领导者跟随者模式,在线程池中的线程可处在3种状态之一:领导者leader、追随者follower或工作者processor。任何时刻线程池只有一个领导者线程。事件到达时,领导者线程负责消息分离,并从处于追随者线程中选出一个来当继任领导者,然后将自身设置为工作者状态去处置该事件。

处理完毕后工作者线程将自身的状态置为追随者。这一模式实现复杂,但避免了线程间交换任务数据,提高了CPUcache相似性。在ACE中,提供了领导者跟随者模式实现。

免责声明:本文转载或采集自网络,版权归原作者所有。本网站刊发此文旨在传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及版权、内容等问题,请联系本网,我们将在第一时间删除。同时,本网站不对所刊发内容的准确性、真实性、完整性、及时性、原创性等进行保证,请读者仅作参考,并请自行核实相关内容。对于因使用或依赖本文内容所产生的任何直接或间接损失,本网站不承担任何责任。

标签: 线程池

“揭秘线程池的七大参数-深化了解其性能和作用 (线程线程池)” 的相关文章

四种常见线程池原理详解-掌握并发编程必备知识 (四种常见线程池)

四种常见线程池原理详解-掌握并发编程必备知识 (四种常见线程池)

线程池是一种用于管理线程的机制,它提供了预先创建的线程集合,这些线程可以重复利用来执行任务。 Java 中的 ExecutorService 接口定义了一组用于管理线程池的方法。Execut...

Java中线程池的优点和使用方法 (java中线程池的参数)

Java中线程池的优点和使用方法 (java中线程池的参数)

线程简介 线程是计算机中执行代码的最小单位,它可以在程序中独立运行,执行特定的任务。线程是稀缺的资源,过多地创建线程会消耗大量的系统资源,并降低系统的稳定性。在高并发的场景下,频繁地创建和销...

并非所有任务都合适-ForkJoinPool-使用-合理的 (并非所有任务的英文)

并非所有任务都合适-ForkJoinPool-使用-合理的 (并非所有任务的英文)

The Stream API is a powerful tool that can be used to process data in a concise and efficient mann...