ThreadPoolExecutor 构造参数:
- corePoolSize:核心池的大小。线程池中基本线程数。当任务队列满后,才会继续创建线程。
- maximumPoolSize:线程池最大线程数,这个参数也是一个非常重要的参数,它表示在线程池中最多能创建多少个线程;
- keepAliveTime:表示线程没有任务执行时最多保持多久时间会终止。
- unit:参数keepAliveTime的时间单位,
- workQueue:一个阻塞队列,用来存储等待执行的任务
- threadFactory:线程工厂,主要用来创建线程
- handler:表示当拒绝处理任务时的策略,有以下四种取值:
- AbortPolicy策略:该策略是线程池默认策略;如果线程池队列满了丢掉这个任务并抛出异常,阻止系统正常工作。
- CallerRunsPolicy 策略:只要线程池未关闭,该策略直接在调用者主线程中,运行当前的被丢弃的任务。
- DiscardOleddestPolicy策略: 该策略将丢弃最老的一个请求,也就是即将被执行的任务,并尝试再次提交当前任务。
- DiscardPolicy策略:如果线程池队列满了,会直接丢掉这个任务并且不会有任何异常。
线程池的工作队列
- ArrayBlockingQueue:是一个基于数组结构的有界阻塞队列,此队列按 FIFO(先进先出)原则对元素进行排序。
- LinkedBlockingQueue:一个基于链表结构的阻塞队列,此队列按FIFO (先进先出) 排序元素,吞吐量通常要高于ArrayBlockingQueue。静态工厂方法Executors.newFixedThreadPool()使用了这个队列
- SynchronousQueue:一个不存储元素的阻塞队列。每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态,吞吐量通常要高于LinkedBlockingQueue,静态工厂方法Executors.newCachedThreadPool使用了这个队列。
- PriorityBlockingQueue:一个具有优先级的无限阻塞队列。
四种常用下线程池:
- FixedThreadPool:(定长线程池)
FixedThreadPool的特点:固定池子中线程的个数。每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。使用静态方法newFixedThreadPool()创建线程池的时候指定线程池个数。 - CachedThreadPool(缓存线程池)
CachedThreadPool的特点:用newCachedThreadPool()方法创建该线程池对象, 创建之初里面一个线程都没有,当execute方法或submit方法向线程池提交任务时, 会自动新建线程;如果线程池中有空余线程,则不会新建;这种线程池一般最多情况可 以容纳几万个线程,里面的线程空余60s会被回收。 - SingleThreadPool(单线程线程池)
SingleThreadPool的特点:池中只有一个线程串行执行所有任务,如果扔5个任务进来,那么有4个任务将排队;作用是保证任务的顺序执行。 - ScheduledThreadpool(定时器线程池):可以延时启动,定时启动的线程池,适用于需要多个后台线程执行周期任务的场景。
注意:要用ScheduledExecutorService去创建ScheduledThreadpool,如果用Executor去引用,就只能调用Executor接口中定义的方法;如果用ExecutorService接 口去引用,就只能调用ExecutorService接口中定义的方法,无法使用ScheduledExecutorService接口中新增的方法,那么也就失去了这种线程池的意义
Executors 创建线程池的两种方式
1.(推荐) ThreadPoolExecutor方式
ExecutorService executorService = new ThreadPoolExecutor(5,10,10,TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(5));
2.Executors方式
ExecutorService threadPool = Executors.newFixedThreadPool(10);
execute 和submit的区别:
execute():无返回值,适用于不需要关注返回值的场景,只需要将线程丢到线程池中去执行就可以了。
submit():有返回值。方法适用于需要关注返回值的场景