为什么要用线程池
- 重复利用线程资源,减少创建、销毁造成的消耗
- 提高响应速度,不需要重新创建
- 统一管理线程
ThredPoolExecutor
corePoolSize
:核心线程数,最少线程数maximumPoolSize
:最大线程数keepAliveTime
:线程池除核心线程外的其他线程的最长空闲时间,超过该时间的空闲线程会被销毁unit
:keepAlivetime的单位,TimeUnit.*
①TimeUnit.DAYS //天
②TimeUnit.HOURS //小时
③TimeUnit.MINUTES //分钟
④TimeUnit.SECONDS //秒
⑤TimeUnit.MILLISECONDS //毫秒⑥TimeUnit.MICROSECONDS //微妙⑦TimeUnit.NANOSECONDS //纳秒workQueue
:缓冲队列
①BlockingQueue 阻塞队列的顶级接口,主要用于实现生产者消费者队列
②BlockingDeque 双端队列
③SynchronousQueue 同步队列,无界队列,直接提交策略,交替队列,在某次添加元素后必须等待其他线程取走后才能继续添加,每个put必须等待一个take; offer()的时候如果没有另一个线程在poll()或者take()的话返回false。
④LinkedBlockingQueue 无界队列,基于链表的阻塞队列,可以并发运行,FIFO, 这是一个由单链表实现的默认无界的阻塞队列。在未指明容量时,容量默认为Integer.MAX_VALUE。
⑤ArrayBlockingQueue 基于数组的有界(固定大小的数组)阻塞队列,只有put方法和take方法才具有阻塞功能,公平性 fairness
⑥PriorityBlockingQueue 基于优先级的阻塞队列,依据对象的自然排序顺序或者是构造函数所带的Comparator决定的顺序
⑦DelayQueue 延时队列threadFactory
:线程工厂,创建线程handler
:当线程池处理不过来时的策略
①ThreadPoolExecutor.AbortPolicy当添加任务出错时,丢弃任务并抛出RejectedExecutionException异常
②ThreadPoolExecutor.DiscardPolicy丢弃任务,但是不抛出异常③ThreadPoolExecutor.DiscardOldestPolicy丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
④ThreadPoolExecutor.CallerRunsPolicy由调用线程处理该任务
执行任务
submit()
该方法返回一个Future对象,可执行带返回值的线程;或者执行想随时可以取消的线程。Future对象的get()方法获取返回值。Future对象的cancel(true/false)取消任务,未开始或已完成返回false,参数表示是否中断执行中的线程execute()
没有返回值。- 处理任务判断的优先级为 核心线程corePoolSize、任务队列workQueue、最大线程maximumPoolSize,如果三者都满了,使用handler处理被拒绝的任务。
shutDown()
不接收新任务,会处理已添加任务shutDownNow()
不接收新任务,中断正在处理的任务
注意- 当workQueue使用的是无界限队列时,maximumPoolSize参数就变的无意义了,比如new LinkedBlockingQueue(),或者new ArrayBlockingQueue(Integer.MAX_VALUE);
- 使用SynchronousQueue队列时由于该队列没有容量的特性,所以不会对任务进行排队,如果线程池中没有空闲线程,会立即创建一个新线程来接收这个任务。maximumPoolSize要设置大一点。
- 核心线程和最大线程数量相等时keepAliveTime无作用.
线程工厂类-Executors
Executors.newCachedThreadPool();
说明: 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程.内部实现:
new ThreadPoolExecutor(0,Integer.MAX_VALUE,60L,TimeUnit.SECONDS,new SynchronousQueue());
Executors.newFixedThreadPool(int);
说明: 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。内部实现:
new ThreadPoolExecutor(nThreads, nThreads,0L,TimeUnit.MILLISECONDS,new LinkedBlockingQueue());
Executors.newSingleThreadExecutor();
说明:创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照顺序执行。内部实现:
new ThreadPoolExecutor(1,1,0L,TimeUnit.MILLISECONDS,new LinkedBlockingQueue())
Executors.newScheduledThreadPool(int);
说明:创建一个定长线程池,支持定时及周期性任务执行。内部实现:
new ScheduledThreadPoolExecutor(corePoolSize);
- 【强制】线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样
的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。 - 【强制】创建线程或线程池时请指定有意义的线程名称,方便出错时回溯。