- 线程池的好处
- 线程池的参数详解
- 线程池种类介绍
- 线程的工作原理 + 策略
- 线程池的Api细节
为什么使用线程池?
- 每个线程的创建、消亡是有开销的,线程池可以重用处在的线程,避免这些开销
- 可以控制最大线程的并发数量,提高系统资源的使用率
- 提供强大API
线程池参数详解
corePoolSize: 核心线程的数量。 当提交一个任务到线程池时,线程池会创建一个核心线程来执行任务,即使其他空闲的核心线程能够执行新任务也会创建新的核心线程 可以理解为当核心线程的数量等于线程池允许的核心线程最大数量的时候,如果有新任务来,就不会创建新的核心线程。
maximumPoolSize: 线程池允许创建的最大线程数 ,如果队列满了,并且已创建的线程数小于最大线程数,则线程池会再创建新的线程执行任务
keepAliveTime: 线程活动保持时间, 即当线程池的工作线程空闲后,保持存活的时间。
TimeUnit: 线程活动保持时间的单位:可选的单位有天(DAYS)、小时(HOURS)、分钟
workQueue : 任务队列:用来保存等待执行任务的阻塞队列
threadFactory: 创建线程的工厂:可以通过线程工厂给每个创建出来的线程设置更加有意义的名字。
线程池的分类:
newCachedThreadPool: 只有非核心线程,最大线程数非常大,所有线程都活动时会为新任务创建新线程,否则会利用空闲线程 ( 60s 空闲时间,过了就会被回收,所以线程池中有 0 个线程的可能 )来处理任务. 优点:(任何任务都会被立即执行,比较适合执行大量的耗时较少的任务)
newFixedThreadPool: 只有核心线程,并且数量固定的,当线程池空闲时不会释放工作线程,还会占用一定的系统资源。优点:更快的响应外界请求
newScheduledThreadPool: 核心线程数固定,非核心线程(闲着没活干会被立即回收数)没有限制.。 优点:执行定时任务以及有固定周期的重复任务
newSingleThreadExecutor: 只有一个核心线程,确保所有的任务都在同一线程中按序完成。 优点:不需要处理线程同步的问题
线程池的工作原理 和策略 一张图解释:
如果超过线程池最大数量,四种策略:
1、AbortPolicy: 默认策略,直接跑出异常阻止系统正常运行
2、CallerRunsPolicy:“调用者运行”一种调节机制,该策略既不会抛弃任务,也不会抛出异常,而是将任务回馈至发起方比如main线程,(哪个线程发起的,会返回去让哪个线程执行任务)
3、DiscardOldestPolicy: 抛弃队列中等待最久的任务,然后把当前任务加入队列中尝试再次提交当前任务
4、DiscardPolicy: 直接丢弃任务,不给予任何处理也不跑出异常,如果允许任务丢失,这是最好的一种方案
线程池几个重要API简介:
线程池提交任务:
1、execute方法用于提交不需要返回值的任务,所以无法判断任务是否被线程池执行成功;
2、submit方法用于提交需要返回值的任务。线程池会返回一个future类型的对象,通过这个future对象可以判断任务是否执行成功,
并且可以通过future的get方法来获取返回值,get方法会阻塞当前线程直到任务完成,而使用get(long
timeout,TimeUnit unit)方法则会阻塞当前线程一段时间后立即返回,这时候有可能任务没有执行完。
关闭线程池
原理: 遍历线程池中的工作线程,然后逐个调用线程的interrupt方法来中断线程,所以无法响应中断的任务可能永远无法终止。
shutdown: 只是将线程池的状态设置为SHUTWDOWN状态,正在执行的任务会继续执行下去,没有被执行的则中断。
shutdownNow: 则是将线程池的状态设置为STOP,正在执行的任务则被停止,没被执行任务的则返回
只要调用了这两个关闭方法中的任意一个,isShutdown方法就会返回true。当所有的任务都关闭后,才表示线程池关闭成功,这时调用isTerminated方法会返回true。至于应该调用哪一个方法来关闭线程池,应该由提交到线程池的任务特性决定,通常调用shutdown方法来关闭线程池,如果任务不一定要执行完,则可以调用shutdownNow方法。