Bootstrap

线程池基础

ThreadPoolExecutor 构造参数:

  1. corePoolSize:核心池的大小。线程池中基本线程数。当任务队列满后,才会继续创建线程。
  2. maximumPoolSize:线程池最大线程数,这个参数也是一个非常重要的参数,它表示在线程池中最多能创建多少个线程;
  3. keepAliveTime:表示线程没有任务执行时最多保持多久时间会终止。
  4. unit:参数keepAliveTime的时间单位,
  5. workQueue:一个阻塞队列,用来存储等待执行的任务
  6. threadFactory:线程工厂,主要用来创建线程
  7. handler:表示当拒绝处理任务时的策略,有以下四种取值:
    1. AbortPolicy策略:该策略是线程池默认策略;如果线程池队列满了丢掉这个任务并抛出异常,阻止系统正常工作。
    2. CallerRunsPolicy 策略:只要线程池未关闭,该策略直接在调用者主线程中,运行当前的被丢弃的任务。
    3. DiscardOleddestPolicy策略: 该策略将丢弃最老的一个请求,也就是即将被执行的任务,并尝试再次提交当前任务。
    4. DiscardPolicy策略:如果线程池队列满了,会直接丢掉这个任务并且不会有任何异常。

线程池的工作队列

  1. ArrayBlockingQueue:是一个基于数组结构的有界阻塞队列,此队列按 FIFO(先进先出)原则对元素进行排序。
  2. LinkedBlockingQueue:一个基于链表结构的阻塞队列,此队列按FIFO (先进先出) 排序元素,吞吐量通常要高于ArrayBlockingQueue。静态工厂方法Executors.newFixedThreadPool()使用了这个队列
  3. SynchronousQueue:一个不存储元素的阻塞队列。每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态,吞吐量通常要高于LinkedBlockingQueue,静态工厂方法Executors.newCachedThreadPool使用了这个队列。
  4. PriorityBlockingQueue:一个具有优先级的无限阻塞队列。

四种常用下线程池:

  1. FixedThreadPool:(定长线程池)
      FixedThreadPool的特点:固定池子中线程的个数。每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。使用静态方法newFixedThreadPool()创建线程池的时候指定线程池个数。
  2. CachedThreadPool(缓存线程池)
      CachedThreadPool的特点:用newCachedThreadPool()方法创建该线程池对象, 创建之初里面一个线程都没有,当execute方法或submit方法向线程池提交任务时, 会自动新建线程;如果线程池中有空余线程,则不会新建;这种线程池一般最多情况可 以容纳几万个线程,里面的线程空余60s会被回收。
  3. SingleThreadPool(单线程线程池)
      SingleThreadPool的特点:池中只有一个线程串行执行所有任务,如果扔5个任务进来,那么有4个任务将排队;作用是保证任务的顺序执行。
  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():有返回值。方法适用于需要关注返回值的场景