线程池基础参数和执行流程

2023-12-15 00:18:49

线程池核心参数

1.corePoolSize:线程池中核心线程的个数。

2.maximumPoolSize:线程池中线程的总数。(线程总数=核心线程数 + 救急线程数)

3.?keepAliveTime:救急线程的存活时间。(救急线程空闲时的存活时间。)

4.unit:存活时间的单位。

5.BlockingQueue:阻塞线程,存储哪些没有被核心线程执行的任务。

6.ThreadFactory:线程工厂,用于创建线程。

7.RejectExecutionHandler:拒绝策略。(当任务在队列中放不下后,执行的策略)

拒绝策略

AbortPolicy:直接抛出异常。(默认策略)

CallRunsPolicy:直接调用主线程执行对应的任务。

DiscardOldestPolicy:丢掉在堵塞队列中存储最久的任务,将新的任务存储到队列中。

DiscardPolicy:直接丢弃任务。

执行原理

1.在新的任务进来后,先判断核心线程是否已满,如果没满,直接创建个核心线程去执行任务。

2.如果核心线程满了,就判断阻塞队列是否已满,如果没有满,直接存储到阻塞队列中。

3.如果阻塞队列满了,就判断线程的总数是否大于核心线程的总数,如果大于,创建救急线程去执行任务。(当救急线程和核心线程处于空闲的时候就会去执行堵塞队列中的方法)

4.如果小于,就去执行对应的拒绝策略。(默认直接报错)

阻塞队列

常用的就是:LinkedBlockQueue和ArrayBlockQueue。都是先进先出的结构。

LinkedBlockQueue和ArrayBlockQueue又什么区别

?1.LinkedBlockQueue默认是无界的(默认的无参构造设置的大小为Integer的最大值),可以设置为有界的,ArrayBlockQueue默认是有界的。

2.LinkedBlockQueue就基于链表实现的,而ArrayBlockQueue是基于数组实现的。

3.LinkedBlockQueue是惰性的,在新增操作的时候才会创建节点,而ArrayBlockQueue则是在最开始的时候就创建节点。

4.LinkedBlockQueue在加锁的时候是对队头和队尾进行加锁,而ArrayBlockQueue是队整个数组进行加锁。(在效率上LinkedBlockQueue比较高)

线程池的种类

1.固定线程数的线程,核心线程数等于总线程数。适用于任务量已知且任务耗时长的时候(不考虑创建救急线程)。

2.单线程的线程池,就只有一个核心线程。按先进先出的策略进行。适用于按照顺序执行的任务。

3.缓存化线程池,没有核心线程,执行任务都是通过救急线程。当没有线程可以执行任务时就会创建救急线程,可以灵活的控制线程的个数,并且堵塞队列中是不存任务的。适用于任务数比较密集,任务执行时间短的时候。

4.计划线程池,可以执行延迟任务的线程池,按周期去执行任务。

不推荐适用Executor创建线程池

1.Executor创建的 固定线程数的线程池和单线程的线程池使用的堵塞队列都是LinkedBlockQueue,并且其初始化长度为Integer.MAX_VALUE,也就是无界的。会出现MMO的情况(内存溢出)。

2.Executor创建的缓存化线程池的线程总数Integer.MAX_VALUE,会出现MMO的情况(内存溢出)。

所以在开发时推荐使用 ThreadPoolExecutor来创建线程池,可以设置具体的参数。

文章来源:https://blog.csdn.net/Ostkakah/article/details/134851192
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。