Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Latest commit

 

History

History
History
49 lines (31 loc) · 2.05 KB

File metadata and controls

49 lines (31 loc) · 2.05 KB
Copy raw file
Download raw file
Outline
Edit and raw actions

线程池原理分析

首先要明确为什么要使用线程池,使用线程池会带来什么好处?

  • 线程是稀缺资源,不能频繁的创建。
  • 应当将其放入一个池子中,可以给其他任务进行复用。
  • 解耦作用,线程的创建于执行完全分开,方便维护。

创建一个线程池

以一个使用较多的

ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) 

为例:

  • 其中的 corePoolSize 为线程池的基本大小。
  • maximumPoolSize 为线程池最大线程大小。
  • keepAliveTimeunit 则是线程空闲后的存活时间。
  • workQueue 用于存放任务的阻塞队列。
  • handler 当队列和最大线程池都满了之后的饱和策略。

处理流程

当提交一个任务到线程池时它的执行流程是怎样的呢?

首先第一步会判断核心线程数有没有达到上限,如果没有则创建线程(会获取全局锁),满了则会将任务丢进阻塞队列。

如果队列也满了则需要判断最大线程数是否达到上限,如果没有则创建线程(获取全局锁),如果最大线程数也满了则会根据饱和策略处理。

常用的饱和策略有:

  • 直接丢弃任务。
  • 调用者线程处理。
  • 丢弃队列中的最近任务,执行当前任务。

所以当线程池完成预热之后都是将任务放入队列,接着由工作线程一个个从队列里取出执行。

合理配置线程池

线程池并不是配置越大越好,而是要根据任务的熟悉来进行划分: 如果是 CPU 密集型任务应当分配较少的线程,比如 CPU 个数相当的大小。

如果是 IO 密集型任务,由于线程并不是一直在运行,所以可以尽可能的多配置线程,比如 CPU 个数 * 2

当是一个混合型任务,可以将其拆分为 CPU 密集型任务以及 IO 密集型任务,这样来分别配置。

Morty Proxy This is a proxified and sanitized view of the page, visit original site.