线程池攻略

线程池

我叫线程池,我的工作就是为我的后台节省效率。简单的说就是减少线程的创建与销毁,毕竟任何指令的执行都需要资源的开销。

corePoolSize

我手下有corePoolSize个助手,假设corePoolSize等于5,也就是我怒呢个创建5个线程。

当有任务来了,我就创建1个助手(线程)让他处理(1号助手)。

此时第二条任务来了,我就再创建1个助手(2号助手),此时我还有创建3个助手能力。

当第三条任务来了,不管现在我的1号,2号助手是否在空闲状态,我都会继续创建助手,知道达到corePoolSize。

我的后台老大跟我说,防止后面突然的任务增多,在那时会产生创建线程的时间,让我先进行创建起来。

workQueue

我的助手无休止的处理任务,如果任务存在的话。某一天,我的后台老大交给了我很多任务,我的助手忙不过来了,这个时候我给他们搭建了亭子,让他们在亭子里面有序的休息等待。亭子也就是workQueue,也就是队列。

可是出现了一个问题,就是亭子里面有时候没有任务等候了,助手一直频繁的查看会产生开销。于是我设置了感应器,当亭子里面来任务的时候,就会唤起我的助手。这个就是阻塞队列,当队列中为非空时,就会唤醒等待中的线程。

好景不长,某一次我发现我的亭子居然一直在塞任务,我看会产生OOM,于是我给我的亭子设置了最大的容纳数目 。

此时我变为了有界队列。

补充:

  • SynchronousQueue

    SynchronousQueue没有容量,是无缓冲等待队列,是一个不存储元素的阻塞队列,会直接将任务交给消费者,必须等队列中的添加元素被消费后才能继续添加新的元素。使用SynchronousQueue阻塞队列一般要求maximumPoolSizes为无界,避免线程拒绝执行操作。

  • LinkedBlockingQueue

    LinkedBlockingQueue是一个无界(没有大小限制)缓存等待队列。当前执行的线程数量达到corePoolSize的数量时,剩余的元素会在阻塞队列里等待,在使用此阻塞队列时maximumPoolSizes就相当于无效了

  • ArrayBlockingQueue

    ArrayBlockingQueue是一个有界缓存等待队列,可以指定缓存队列的大小,当线程数量大于corePoolSize时,多余的任务会缓存在ArrayBlockingQueue队列中等待有空闲的线程时继续执行;当ArrayBlockingQueue满时,则又会开启新的线程去执行,直到线程数量达到maximumPoolSize;当线程数已经达到最大的maximumPoolSize时,再有新的任务到达时会执行拒绝执行策略(RejectedExecutionException)

maximumPoolSize

但是上面的问题还是没有彻底解决,我发现还是有源源不断的任务进来,此时我的5个助手已经忙不过来了。

我的后来老大看到后,给我设置了maximumPoolSize,最大线程数目(8),也就是我还能创建3个助手。但是是有条件的,当workQueue已经满且助手数目小于8(maximumPoolSize)的情况下,依然有任务想要插入,我才可以进行创建。

RejectedExecutionHandler

当任务不断 的插入到workQueue中的时候,workQueue已经无法接受了,此时我会执行默认的拒绝策略,抛出异常。

线程池提供了 AbortPolicy,DiscardPolicy,DiscardOldestPolicy,CallerRunsPolicy,自定义这五种拒绝策略,默认是 AbortPolicy。

keepAliveTime

时间荏苒,突然有一次,发现workQueue中的队列任务没有了。助手们就一直闲着。但是我的corePoolSize是5,maximumPoolSize是8 ,为了节约成本需要进行回收。此时看谁休息的时间最长就把他进行回收,设置了一个休息时间的截止时间。keepAliveTime,也就是哪个线程先达到keepAliveTime,就先干掉,直到等于5(corePoolSize)。

本文标题:线程池攻略

文章作者:wsylp

发布时间:2020年11月26日 - 18:11

最后更新:2020年11月26日 - 20:11

原始链接:http://wsylp.github.io/2020/11/26/线程池攻略/

许可协议: 本文为 wsylp 版权所有 转载请保留原文链接及作者。

-------------本文结束感谢阅读-------------