Java线程池笔记

简介: 总结一下Java线程池相关八股文

Java相关文章


线程池参数

  1. corePoolSize 线程池核心线程数
  1. 线程池中会维护一个最小的线程数量,即使这些线程处理空闲状态,他们也不会被销毁,除非设置了allowCoreThreadTimeOut。这里的最小线程数量即是corePoolSize。
  1. maximumPoolSize 线程池最大线程数量
  1. 一个任务被提交到线程池以后,首先会找有没有空闲存活线程,如果有则直接将任务交给这个空闲线程来执行,如果没有则会缓存到工作队列(后面会介绍)中,如果工作队列满了,才会创建一个新线程,然后从工作队列的头部取出一个任务交由新线程来处理,而将刚提交的任务放入工作队列尾部。线程池不会无限制的去创建新线程,它会有一个最大线程数量的限制,这个数量即由maximunPoolSize指定。
  1. keepAliveTime 空闲线程存活时间
  1. 一个非核心线程如果处于空闲状态,并且当前的线程数量大于corePoolSize,那么在指定时间后,这个空闲线程会被销毁,这里的指定时间由keepAliveTime来设定
  1. unit 空闲线程存活时间单位
  1. keepAliveTime的计量单位
  1. workQueue 工作队列
  1. ArrayBlockingQueue
  1. 数组有界大小固定
  2. 基于数组的有界阻塞队列,按FIFO排序。新任务进来后,会放到该队列的队尾,有界的数组可以防止资源耗尽问题。当线程池中线程数量达到corePoolSize后,再有新任务进来,则会将任务放入该队列的队尾,等待被调度。如果队列已经是满的,则创建一个新线程,如果线程数量已经达到maxPoolSize,则会执行拒绝策略。
  1. LinkedBlockingQuene
  1. 链表有界大小可变
  2. 基于链表的无界阻塞队列(其实最大容量为Interger.MAX),按照FIFO排序。由于该队列的近似无界性,当线程池中线程数量达到corePoolSize后,再有新任务进来,会一直存入该队列,而不会去创建新线程直到maxPoolSize,因此使用该工作队列时,参数maxPoolSize其实是不起作用的。
  1. SynchronousQuene
  1. SynchronousQueue的capacity是0,该队列不存储任何元素
  2. 也就是说SynchronousQueue的每一次insert操作,必须阻塞到其他线程的remove操作。而每一个remove操作也必须阻塞其他线程的insert操作。
  1. PriorityBlockingQueue
  1. 具有优先级的无界阻塞队列,优先级通过参数Comparator实现。
  1. 队列管理任务方法

抛出异常

特殊值

阻塞

超时

插入

add(e)

offer(e)

put(e)

offer(e, time, unit)

移除

remove()

poll()

take()

poll(time, unit)

检查

element()

peek()

不可用

不可用



handler 拒绝策略

  1. CallerRunsPolicy
  1. 该策略下,在调用者线程中直接执行被拒绝任务的run方法,除非线程池已经shutdown,则直接抛弃任务。
  1. AbortPolicy
  1. 该策略下,直接丢弃任务,并抛出RejectedExecutionException异常。
  1. DiscardPolicy
  1. 该策略下,直接丢弃任务,什么都不做。
  1. DiscardOldestPolicy
  1. 该策略下,抛弃进入队列最早的那个任务,然后尝试把这次拒绝的任务放入队列


线程池核心线程数为0任务怎么创建

  1. 当核心线程数为0的时候,会创建一个非核心线程进行执行
  2. 核心线程数不为0的时候,如果核心线程数在执行,会有一个非核心线程数从队列中取对象执行线程
  3. 核心线程数执行的是队列的take,非核心线程数执行队列的offer和poll
  4. 核心线程数不为0且队列为SynchronousQueue时,就成了单线程运行了


线程池一个任务从被提交到被执行,线程池做了哪些工作?

  1. 线程池刚创建时,里面没有一个线程。任务队列是作为参数传进来的。不过,就算队列里面有任务,线程池也不会马上执行他们。
  2. 当调用execute()方法添加一个任务时,线程池会做如下判断:
  1. 如果正在运行的线程数量小于corePoolSize,那么马上创建线程运行这个任务
  2. 如果正在运行的线程数量大于或等于corePoolSize,那么将这个任务放入队列
  3. 如果这时候队列满了,而且正在运行的线程数量小于maximunPoolSize,那么还是要创建非核心线程立刻运行这个任务
  4. 如果队列满了,而且正在运行的线程数量大于或等于maximunPoolSize,那么线程池会抛出RejectedExecutionException
  1. 当一个线程完成任务时,它会从队列中取下一个任务来执行
  2. 当一个线程无事可做,超过一定的时间(keepAliveTime)时,线程池会判断,如果当前运行的线程数大于corePoolSize,那么这个线程就被停掉。所以线程池的所有任务完成后,它最终会收缩到corePoolSize的大小



常见线程池有哪些

  1. newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
  2. newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
  3. newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
  4. newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
相关文章
|
3天前
|
Java 数据库
【Java多线程】对线程池的理解并模拟实现线程池
【Java多线程】对线程池的理解并模拟实现线程池
16 1
|
3天前
|
Java
Java并发编程:深入理解线程池
【4月更文挑战第30天】本文将深入探讨Java并发编程中的一个重要主题——线程池。我们将从线程池的基本概念入手,了解其工作原理和优势,然后详细介绍如何使用Java的Executor框架创建和管理线程池。最后,我们将讨论一些高级主题,如自定义线程工厂和拒绝策略。通过本文的学习,你将能够更好地理解和使用Java的线程池,提高你的并发编程能力。
|
4天前
|
Java 程序员 数据库
Java线程池让使用线程变得更加高效
使用一个线程需要经过创建、运行、销毁三大步骤,如果业务系统每个线程都要经历这个过程,那会带来过多不必要的资源消耗。线程池就是为了解决这个问题而生,需要时就从池中拿取,使用完毕就放回去,池化思想通过复用对象大大提高了系统的性能。线程池、数据库连接池、对象池等都采用了池化技术,下面我们就来学习下线程池的核心知识、面试重点~
62 5
Java线程池让使用线程变得更加高效
|
23小时前
|
存储 Java
【Java】实现一个简单的线程池
,如果被消耗完了就说明在规定时间内获取不到任务,直接return结束线程。
8 0
|
23小时前
|
存储 缓存 调度
FFmpeg开发笔记(十九)FFmpeg开启两个线程分别解码音视频
《FFmpeg开发实战》第10章示例playsync.c在处理音频流和视频流交错的文件时能实现同步播放,但对于分开存储的格式,会出现先播放全部声音再快速播放视频的问题。为解决此问题,需改造程序,增加音频处理线程和队列,以及相关锁,先将音视频帧读入缓存,再按时间戳播放。改造包括声明新变量、初始化线程和锁、修改数据包处理方式等。代码修改后在playsync2.c中,编译运行成功,控制台显示日志,SDL窗口播放视频并同步音频,证明改造有效。
7 0
FFmpeg开发笔记(十九)FFmpeg开启两个线程分别解码音视频
|
2天前
|
Java 测试技术 开发工具
Android 笔记:AndroidTrain , Lint , build(1),只需一篇文章吃透Android多线程技术
Android 笔记:AndroidTrain , Lint , build(1),只需一篇文章吃透Android多线程技术
|
4天前
|
Java 调度
Java一分钟之线程池:ExecutorService与Future
【5月更文挑战第12天】Java并发编程中,`ExecutorService`和`Future`是关键组件,简化多线程并提供异步执行能力。`ExecutorService`是线程池接口,用于提交任务到线程池,如`ThreadPoolExecutor`和`ScheduledThreadPoolExecutor`。通过`submit()`提交任务并返回`Future`对象,可检查任务状态、获取结果或取消任务。注意处理`ExecutionException`和避免无限等待。实战示例展示了如何异步执行任务并获取结果。理解这些概念对提升并发性能至关重要。
18 5
|
3天前
|
Java 调度
Java并发编程:深入理解线程池
【5月更文挑战第11天】本文将深入探讨Java中的线程池,包括其基本概念、工作原理以及如何使用。我们将通过实例来解释线程池的优点,如提高性能和资源利用率,以及如何避免常见的并发问题。我们还将讨论Java中线程池的实现,包括Executor框架和ThreadPoolExecutor类,并展示如何创建和管理线程池。最后,我们将讨论线程池的一些高级特性,如任务调度、线程优先级和异常处理。
|
3天前
|
Java
线程池笔记
线程池笔记
8 0
|
4天前
|
缓存 Java
Java并发编程:深入理解线程池
【5月更文挑战第7天】本文将深入探讨Java并发编程中的重要概念——线程池。我们将了解线程池的基本概念,以及如何使用Java的Executor框架来创建和管理线程池。此外,我们还将讨论线程池的优点和缺点,以及如何选择合适的线程池大小。最后,我们将通过一个示例来演示如何使用线程池来提高程序的性能。