线程池工作原理及参数

线程池

线程池的作用

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

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

  • 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:获取活动的线程数

你可能感兴趣的:(java,java,JUC,线程池)