当前位置: 代码迷 >> J2SE >> [原]java线程API学习 线程池ThreadPoolExecutor解决方法
  详细解决方案

[原]java线程API学习 线程池ThreadPoolExecutor解决方法

热度:599   发布时间:2016-04-23 22:26:15.0
[原]java线程API学习 线程池ThreadPoolExecutor
    线程池ThreadPoolExecutor继承自ExecutorService。是jdk1.5加入的新特性,将提交执行的任务在内部线程池中的可用线程中执行。

    构造函数

    ThreadPoolExecutor(int corePoolSize,
                                  int maximumPoolSize,
                                  long keepAliveTime,
                                  TimeUnit unit,
                                  BlockingQueue<Runnable> workQueue,
                                  ThreadFactory threadFactory,
                                  RejectedExecutionHandler handler)

    corePoolSize 线程池维护的核心线程数。为什么这里说核心线程数而不是最小线程数是因为在线程池被创建后,并不会直接创建corePoolSize个线程,而是等任务到来时临时创建。等按照需要创建了corePoolSize个线程之后,这些数量的线程即使闲置,也不会被线程池收回。这时即可以将这个值理解为线程池维护的最小线程数了。
    maximumPoolSize 线程池维护的最大线程数。
    keepAliveTime 当线程池中的线程数量大于corePoolSize,多出那部分数量的线程空闲keepAliveTime后会被收回。
    unit keepAliveTime的时间单位。可选的参数为java.util.concurrent.TimeUnit中的几个静态属性:NANOSECONDS、MICROSECONDS、MILLISECONDS、SECONDS。
    workQueue 存放通过execute方法提交给线程等待执行的任务的队列。
    threadFactory 负责给线程池创建线程的工厂。
    handler 在当队列达到极限导致任务执行阻塞时执行的处理策略。handler有四个选择:ThreadPoolExecutor.AbortPolicy(抛出java.util.concurrent.RejectedExecutionException异常)。ThreadPoolExecutor.CallerRunsPolicy(重试添加当前的任务,他会自动重复调用execute方法)。ThreadPoolExecutor.DiscardOldestPolicy(抛弃旧的任务)。
    ThreadPoolExecutor.DiscardPolicy(抛弃当前的任务)。

    对于一般的应用,我们不用通过构造函数来创建线程池,而是用一些封装过的工具方法,这些方法设置了大多数参数的缺省值。只有对线程池的特性有更高的要求时,才直接使用构造函数。

    Executors.newCachedThreadPool(创建自动增加或减少容量的线程池)

    Executors.newFixedThreadPool(创建固定容量的线程池)

    Executors.newSingleThreadExecutor(单独线程的线程池)。

    下面是一些高级特性
    · 关于corePoolSize和maximumPoolSize

    ThreadPoolExecutor会根据corePoolSize和maximumPoolSize的值调整线程池中线程的数量。当通过ThreadPoolExecutor.execute方法向线程池提交一个新的任务时,如果线程池当前线程数量小于corePoolSize,就算有线程空闲,也会在创建一个线程执行这个任务;如果线程池当前线程数量大于corePoolSize又小于maximumPoolSize,只有当可用线程不够的时候才会创建新的线程。如果不希望系统动态增减线程数量,则将corePoolSize和maximumPoolSize数值设置为一样的值。如果将maximumPoolSize设置为一个特别大的值如Integer.MAX_VALUE,则ThreadPoolExecutor成为了一个能够容纳大量并发任务的线程池。一般来说corePoolSize和maximumPoolSize是在构造ThreadPoolExecutor对象时设置好的,当仍然可以调用ThreadPoolExecutor.setCorePoolSize 和ThreadPoolExecutor.setMaximumPoolSize 方法修改这两个属性。
    · 关于线程创建

    线程池中的线程是由ThreadFactory创建。如果不特别指定,会使用Executors.defaultThreadFactory创建位于同一个线程组,相同优先级(NORM_PRIORITY)的非守护线程。如果由你来指定ThreadFactory,你可以定制线程名字,线程组,优先级,是否为守护线程等属性。

· 直到需要时才开始创建线程

缺省情况下,在线程池刚刚创建好之后其中是没有任何线程存在的。直到向线程池中提交了任务。可以通过复写ThreadPoolExecutor.perstartCoreThread或ThreadPoolExecutor.prestartAllCoreThreads方法改变默认行为。
  相关解决方案