BlockingQueue接口和线程池

Posted shizhuoping

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BlockingQueue接口和线程池相关的知识,希望对你有一定的参考价值。

BlockingQueue接口和线程池

BlockingQueue接口

它有四套api,add/remove操作失败会直接抛出异常,offer/poll操作失败会返回特殊值,还可以加时间,过了时间返回失败,put/take操作失败会阻塞。

ArrayBlockingQueue:是数组实现的,必须构造时传入大小,传入后不可改变。

DelayQueue:实现Delay接口,与排序有关,它是一个可以实现排序的队列,内部就是堆

LinkedBlockingQueue:可以指定大小也可以不指定,内部实现是链表

PriorityBlockingQueue:是有优先级的队列,允许插入元素为null,所有其中对象必须实现Comparable接口。

SynchronousQueue:内部仅容纳一个元素,当一个线程放入元素后就会被阻塞,直到这个元素被消费,又称为同步队列

线程池ThreadPoolExecutor

ThreadPoolExecutor的7个构造参数:

核心线程数量:如果运行线程数少于这个值直接创建新线程,即使线程池中线程是空闲的

最大线程数:当大于核心线程少于最大线程时,只有当阻塞队列满了才会创建新线程,当核心线程数和最大线程数相同的时候,线程池大小是固定的,新任务提交会把它放在阻塞队列中等待。

阻塞队列:有三种模式,第一就是使用SynchronousQueue,它会把任务直接切换到运行态,当为无界队列(linked)时最大线程数这个参数就会失效,还有有界队列(array)。如果为有界队列,那么队列容量、核心线程数、最大线程数三个参数可以好好调节,如果要降低CPU消耗可以设置大队列小线程池,提升CPU使用率要设置小队列大线程池,线程池大小也不能太大,否则效率反而会变小

线程空闲时间:空闲的线程多久会被回收

时间单位

线程工厂:默认所有线程都有相同的优先级

拒绝策略:队列满了且没有空闲线程时,如果提交任务就会采用策略来对待这个任务,默认为直接抛出异常,还可以用调用者所在线程执行任务、丢弃队列中最靠前的任务执行当前任务、直接丢弃这个任务。

Executors

Executors可以创建的线程池:返回值都是ExecutorService,它没有查询功能。

newCachedThreadPool,一个可以动态大小的线程池,可以灵活回收或新建

newFixedThreadPool,一个固定大小的线程池,可以控制线程的最大并发数,超出的放入队列等待。

newScheduledThreadPool:一个定长的线程池,支持定时和周期任务执行,它调用schedule可以设置延时一段时间后执行,还可以以指定速率执行任务,指定的延时间隔执行任务

newSingleThreadExecutor:一个单线程的线程池,保证任务串行

线程池的方法

线程池提交:execute和submit,后者可以结合future得到线程计算结果

线程池关闭:shutdown和shutdownNow,后者不会等待任务执行完

线程池查询:可以得到任务总数(包括已经执行的)、已完成的任务数量、当前线程数量、正在执行任务的线程数量。

线程池的状态

running:能处理新任务,也可以处理阻塞队列中的任务

shutdown:不能接受新任务,但是可以处理阻塞队列中的任务,调用shutdown方法可以到该状态。

stop:不能接受新任务,也不处理阻塞队列中的任务,调用shutdownNow会进入该状态

tidying:所有任务都完成了进入该状态

terminated:从tidying转变过来的最终状态

线程数量和线程池任务选择

线程数量:CPU密集型要尽量压榨CPU,设置为CPU数+1,而IO密集型要设置为2倍的CPU数量

适合用线程池的任务:大任务。如果任务执行的速度和线程池管理的速度相当,反而会降低程序运行速度。

以上是关于BlockingQueue接口和线程池的主要内容,如果未能解决你的问题,请参考以下文章

Java并发编程:4种线程池和缓冲队列BlockingQueue

hreadPoolExecutor使用和思考(上)-线程池大小设置与BlockingQueue的三种实现区别

JAVA线程池ThreadPoolExecutor与阻塞队列BlockingQueue

线程池ThreadPoolExecutor与阻塞队列BlockingQueue应用

定时器线程池(ScheduledThreadPoolExecutor)

java阻塞队列 线程同步合作