线程池工作原理及参数

线程池

线程池的作用

  • 降低资源的消耗
  • 提高响应速度
  • 提高线程的客观理性

当一个新任务到达线程池时,其处理流程?

  • 1、线程池判断核心线程池的线程是否都在执行任务。

是:进入下个流程

否:创建一个新的工作线程来执行任务(需要加上全局锁)

工作线程:线程池创建线程时,会将线程封装成工作线程Worker,Worker在执行完任务后,还会循环获取工作队列里的任务来执行

  • 2、线程池判断工作队列是否已满

是:进入下个流程

否:将新提交的任务存储在工作队列中

  • 3、线程池判断线程池的线程是否都处于工作状态

是:交给饱和策略来处理

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

CallerRunsPolicy:只用调用者所在的线程来执行任务

DiscardOldestPolicy:丢弃队列里最近的一个任务,并执行当前任务

DiscardPolicy:不处理,直接丢弃

否:创建新的工作线程来执行任务(需要加上全局锁)

介绍一下线程池的参数

  • 1、corePoolSize:线程池的基本大小

当提交一个任务到线程池时,线程池会创建一个线程来执行任务,即是其他空闲的基本线程能够执行新的任务,也会创建这个线程,等到需要执行的任务数大于线程池的基本大小的时候就不再创建

  • 2、runnableTaskQueue:任务队列(用来保存等待执行任务的阻塞队列)

1、ArrayBlockingQueue:是一个基于数组结构的有界阻塞队列,进入队列的元素按照FIFO排序

2、LinkedBlockingQueue:一个基于链表的阻塞队列,元素按照FIFO排序,吞吐量通常要改于ArrayBlockingQueue,eg:Executors.newFixedThreadPool()

3、SynchronousQueue:一个不存储元素的阻塞队列,每个插入操作必须等到另一个进程调用移除操作,否则插入操作一直处于阻塞状态,吞吐量通常高于LinkedBlockingQueue。eg:Executors.newCachedThreadPool()

4、PriorityBlockingQueue:一个具有优先级的无限阻塞队列

  • 3、maximumPoolSize:线程池最大数量

线程允许创建的最大线程数。如果队列满了,并且已创建的线程数小于最大线程数,则线程池会再创建新的线程执行任务。注意:如果是使用了上述的无界的任务队列,就没必要开启这个最大线程数的参数

  • 4、ThreadFactory:用于设置创建线程的工厂

new ThreadFactoryBuilder().setNameFormat(“xxx-task–%d”).get();

  • 5、RejectedExecutionHandler:饱和策略

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

CallerRunsPolicy:只用调用者所在的线程来执行任务

DiscardOldestPolicy:丢弃队列里最近的一个任务,并执行当前任务

DiscardPolicy:不处理,直接丢弃

  • 6、keepAliveTime:线程活动保持时间

线程池的工作线程空闲后,可以存活的最长时间

  • 7、TimeUnit:线程活动保持时间的单位

存活时间的单位

如何向线程池中提交任务?

  • 1、execute()方法

用于提交不需要返回值的任务,所以无法判断任务是否被线程池执行成功。

  • 2、submit()方法

用于提交需要返回值的任务,线程池会返回一个future对象,通过future对象可以判断任务是否执行成功,可以使用future.get()方法来获得返回值。

如何关闭线程池?

  • shutdown

  • shutdownNow

使用了上述两个中的任意一个,都会使得 isShutDown 返回 true。至所有任务都关闭后,表示线程池关闭成功,此时 isTerminated 会返回true

如何合理的配置线程池?

  • 1、任务的性质

CPU密集型任务:尽可能配置小的线程,因为是一直在执行任务,无需一直进行线程的切换

IO密集型任务:并不是一直在执行任务,可以配置尽可能多的线程。

混合型任务:可以拆分成一个CPU密集型的任务和一个IO密集型的任务,只要是任务的相差时间不是很长,效率肯定会比未拆分之前要高。

  • 2、任务的优先级

PriorityBlockingQueue

  • 3、任务的执行时间

  • 4、任务的依赖性

是否依赖其他的系统资源。eg:数据库连接

如何对线程池进行监控?

taskCount:线程池需要执行的任务的数量

completedTaskCount:线程池已经完成的线程的数量,总量应小于taskCount

largestPoolSize:线程池里曾经创建的最大线程数量,根据该值可以知道线程池之前是否满过,加入largestPoolSize等于线程池的最大大小,说明之前满过

getPoolSize:线程池的线程数量,只要是线程池不销毁的话,线程不会自动销毁,该值只增不减

getActiveCount:获取活动的线程数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Java线程池是一种管理线程的技术,它通过复用已经创建好的线程来提高性能和资源利用率。核心参数主要包括以下几个方面: 1. **核心池大小** (`corePoolSize`): 线程池默认启动的最大线程数。即使所有任务都在队列中等待处理,也不会超过这个数量。当任务提交并有新线程可用时,多余的线程会立即停止。 2. **最大池大小** (`maximumPoolSize`): 线程池允许的最大线程数。如果超过了这个限制,新的任务将会进入阻塞队列等待,直到有空闲线程可用。 3. **任务队列** (`queue`): 提交的任务在此排队等待。常见的选项包括 `BlockingQueue` 类型,如 `LinkedList`、`ArrayBlockingQueue` 和 `LinkedBlockingQueue`,也可以自定义。 4. **线程工厂** (`threadFactory`): 用于创建新线程的工厂,可以设置线程属性如名称、优先级等。 5. **拒绝策略** (`handler`): 当任务队列已满且最大线程数也达到上限,如何处理新任务。选项有 `AbortPolicy` (默认) 异常抛出,`CallerRunsPolicy` 由提交任务的线程直接运行,`DiscardOldestJobPolicy` 删除队列最老的任务。 工作原理: - 当有新任务提交到线程池时,首先检查核心池内的线程是否足够。如果足够,则交给线程去执行;如果不足,则创建新线程。 - 如果线程池已满,任务会被放入队列中等待,直到有线程完成或线程池的大小减小。 - 当线程完成后,它们可能会返回到核心池,也可能因拒绝策略而结束,如超时或达到最大线程数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BXuan随笔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值