java并发之线程池

  自从看了《JAVA并发编程实战》,最吸引我的除了AQS构造的一系列同步器以外,就是线程池了,今天就来讲讲JAVA的线程池。

1.构造方法以及主要参数

  之前我翻源码是从成员变量看起,不过由于ThreadPoolExecutor的变量有点小多,那么就先从构造方法开始。先找到下面那个最全的构造器:

 1     /**
 2      * Creates a new {@code ThreadPoolExecutor} with the given initial
 3      * parameters.
 4      *
 5      * @param corePoolSize the number of threads to keep in the pool, even
 6      *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
 7      * @param maximumPoolSize the maximum number of threads to allow in the
 8      *        pool
 9      * @param keepAliveTime when the number of threads is greater than
10      *        the core, this is the maximum time that excess idle threads
11      *        will wait for new tasks before terminating.
12      * @param unit the time unit for the {@code keepAliveTime} argument
13      * @param workQueue the queue to use for holding tasks before they are
14      *        executed.  This queue will hold only the {@code Runnable}
15      *        tasks submitted by the {@code execute} method.
16      * @param threadFactory the factory to use when the executor
17      *        creates a new thread
18      * @param handler the handler to use when execution is blocked
19      *        because the thread bounds and queue capacities are reached
20      * @throws IllegalArgumentException if one of the following holds:<br>
21      *         {@code corePoolSize < 0}<br>
22      *         {@code keepAliveTime < 0}<br>
23      *         {@code maximumPoolSize <= 0}<br>
24      *         {@code maximumPoolSize < corePoolSize}
25      * @throws NullPointerException if {@code workQueue}
26      *         or {@code threadFactory} or {@code handler} is null
27      */
28     public ThreadPoolExecutor(int corePoolSize,
29                               int maximumPoolSize,
30                               long keepAliveTime,
31                               TimeUnit unit,
32                               BlockingQueue<Runnable> workQueue,
33                               ThreadFactory threadFactory,
34                               RejectedExecutionHandler handler) {
View Code

  七个参数:

  corePoolSize:

    保留在线程池中的线程数量(核心线程数),不会被回收的线程,即时是空闲的(除非设置了 {@code allowCoreThreadTimeOut})

  maximumPoolSize:

    最大线程数≥核心线程数,可同时活动的线程上限。

  keepAliveTime:

    定义非核心线程空闲keepAliveTime后被回收。

  unit:

    时间单位,可以查看TimeUint枚举,包含秒,毫秒,纳秒等单位。

  workQueue:

    工作队列如果线程数超过核心线程数,则多余的任务将会等待在这个队列中,主要包含:SynchronousQueue、LinkedBlockingQueue、ArrayBlockingQueue。

  threadFactory:

    工厂使用时执行者,一般使用DefaultThreadFactory。

  handler:

    处理程序在阻止执行时使用的处理程序,拒接策略,一般使用AbortPolicy。

    饱和策略包括:(摘自JAVA并发编程实战p144)

      AbortPolicy:中止、抛出异常。

      CallerRunsPolicy:将某些任务退回到调用者、降低新任务的流量。

      DiscardPolicy:会悄悄的抛弃任务。

      DiscardOldestPolicy:抛弃将被执行的下一个任务,然后尝试重新提交新任务(最好不要和优先队列一起使用,防止抛弃优先级最高的任务)。

 

2.Executros静态方法构造:

  Executors工具类提供了四种主要的线程池:
  newFixedThreadPool:核心线程数和最大线程数一样(入参),使用LinkedBlockingQueue作为阻塞队列
  newSingleThreadExecutor:核心线程数和最大线程数都是1,使用LinkedBlockingQueue作为阻塞队列
  newCachedThreadPool:不设置核心线程数,最大线程数为Integer.MAX_VALUE,使用SynchronousQueue作为阻塞队列线程数大于最大线程数时,会因为线程池拒绝添加任务抛出异常,超时时间设置成1分钟
  newScheduledThreadPool:核心线程数(入参),最大线程数Integer.MAX_VALUE,使用DelayedWorkQueue,该队列和另外三种阻塞队列不太一样的是这个类的泛型指定为runnable,个人猜测主要设计用在线程池中提供可调度的线程池而构造的。

  阿里开发手册上似乎不建议使用Executros的静态方法直接生成线程池,应该是为了防止对参数设置了解不多而造成一系列问题,不过在查看源码的过程中借鉴这个工具类,能帮助我们更快的了解那些参数以及根据需求设计线程池。

 

3.submit 和execute 区别:

  sumbit:父类AbstractExecutorService中的方法,返回Future,可以用Future.get()获取执行的返回值。

  execute:ThreadPoolExecutror中的方法,执行任务,sumbit方法中也是使用execute执行任务,只不过execute无法获得返回值。

 

posted @ 2018-07-14 20:23  zhangdapao  阅读(208)  评论(0编辑  收藏  举报