大家好,我是冰河~~

在Java的高并发畛域,线程池始终是一个绕不开的话题。有些童鞋始终在应用线程池,然而,对于如何创立线程池仅仅停留在应用Executors工具类的形式,那么,创立线程池到底存在哪几种形式呢?就让咱们一起从创立线程池的源码来深入分析到底有哪些形式能够创立线程池。

应用Executors工具类创立线程池

在创立线程池时,初学者用的最多的就是Executors 这个工具类,而应用这个工具类创立线程池时非常简单的,不须要关注太多的线程池细节,只须要传入必要的参数即可。Executors 工具类提供了几种创立线程池的办法,如下所示。

  • Executors.newCachedThreadPool:创立一个可缓存的线程池,如果线程池的大小超过了须要,能够灵便回收闲暇线程,如果没有可回收线程,则新建线程
  • Executors.newFixedThreadPool:创立一个定长的线程池,能够控制线程的最大并发数,超出的线程会在队列中期待
  • Executors.newScheduledThreadPool:创立一个定长的线程池,反对定时、周期性的工作执行
  • Executors.newSingleThreadExecutor: 创立一个单线程化的线程池,应用一个惟一的工作线程执行工作,保障所有工作依照指定程序(先入先出或者优先级)执行
  • Executors.newSingleThreadScheduledExecutor:创立一个单线程化的线程池,反对定时、周期性的工作执行
  • Executors.newWorkStealingPool:创立一个具备并行级别的work-stealing线程池

其中,Executors.newWorkStealingPool办法是Java 8中新增的创立线程池的办法,它可能为线程池设置并行级别,具备更高的并发度和性能。除了此办法外,其余创立线程池的办法实质上调用的是ThreadPoolExecutor类的构造方法。

例如,咱们能够应用如下代码创立线程池。

Executors.newWorkStealingPool();Executors.newCachedThreadPool();Executors.newScheduledThreadPool(3);

应用ThreadPoolExecutor类创立线程池

从代码构造上看ThreadPoolExecutor类继承自AbstractExecutorService,也就是说,ThreadPoolExecutor类具备AbstractExecutorService类的全副性能。

既然Executors工具类中创立线程池大部分调用的都是ThreadPoolExecutor类的构造方法,所以,咱们也能够间接调用ThreadPoolExecutor类的构造方法来创立线程池,而不再应用Executors工具类。接下来,咱们一起看下ThreadPoolExecutor类的构造方法。

ThreadPoolExecutor类中的所有构造方法如下所示。

public ThreadPoolExecutor(int corePoolSize,                  int maximumPoolSize,                  long keepAliveTime,                  TimeUnit unit,                 BlockingQueue<Runnable> workQueue) {    this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,         Executors.defaultThreadFactory(), defaultHandler);}public ThreadPoolExecutor(int corePoolSize,                int maximumPoolSize,                long keepAliveTime,                TimeUnit unit,                BlockingQueue<Runnable> workQueue,                    ThreadFactory threadFactory) {this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,     threadFactory, defaultHandler);}public ThreadPoolExecutor(int corePoolSize,                int maximumPoolSize,                long keepAliveTime,                    TimeUnit unit,                BlockingQueue<Runnable> workQueue,                RejectedExecutionHandler handler) {this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,     Executors.defaultThreadFactory(), handler);}public ThreadPoolExecutor(int corePoolSize,                int maximumPoolSize,                long keepAliveTime,                TimeUnit unit,                    BlockingQueue<Runnable> workQueue,                ThreadFactory threadFactory,                RejectedExecutionHandler handler) {    if (corePoolSize < 0 ||        maximumPoolSize <= 0 ||        maximumPoolSize < corePoolSize ||        keepAliveTime < 0)        throw new IllegalArgumentException();    if (workQueue == null || threadFactory == null || handler == null)        throw new NullPointerException();    this.acc = System.getSecurityManager() == null ?            null :            AccessController.getContext();    this.corePoolSize = corePoolSize;    this.maximumPoolSize = maximumPoolSize;    this.workQueue = workQueue;    this.keepAliveTime = unit.toNanos(keepAliveTime);    this.threadFactory = threadFactory;    this.handler = handler;}

由ThreadPoolExecutor类的构造方法的源代码可知,创立线程池最终调用的构造方法如下。

public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize,              long keepAliveTime, TimeUnit unit,              BlockingQueue<Runnable> workQueue,              ThreadFactory threadFactory,                  RejectedExecutionHandler handler) {    if (corePoolSize < 0 ||        maximumPoolSize <= 0 ||        maximumPoolSize < corePoolSize ||        keepAliveTime < 0)        throw new IllegalArgumentException();    if (workQueue == null || threadFactory == null || handler == null)        throw new NullPointerException();    this.acc = System.getSecurityManager() == null ?            null :            AccessController.getContext();    this.corePoolSize = corePoolSize;    this.maximumPoolSize = maximumPoolSize;    this.workQueue = workQueue;    this.keepAliveTime = unit.toNanos(keepAliveTime);    this.threadFactory = threadFactory;    this.handler = handler;}

对于此构造方法中各参数的含意和作用,各位能够移步《高并发之——不得不说的线程池与ThreadPoolExecutor类浅析》进行查阅。

大家能够自行调用ThreadPoolExecutor类的构造方法来创立线程池。例如,咱们能够应用如下模式创立线程池。

new ThreadPoolExecutor(0, Integer.MAX_VALUE,                       60L, TimeUnit.SECONDS,                       new SynchronousQueue<Runnable>());

应用ForkJoinPool类创立线程池

在Java8的Executors工具类中,新增了如下创立线程池的形式。

public static ExecutorService newWorkStealingPool(int parallelism) {    return new ForkJoinPool        (parallelism,         ForkJoinPool.defaultForkJoinWorkerThreadFactory,         null, true);}public static ExecutorService newWorkStealingPool() {    return new ForkJoinPool        (Runtime.getRuntime().availableProcessors(),         ForkJoinPool.defaultForkJoinWorkerThreadFactory,         null, true);}

从源代码能够能够,实质上调用的是ForkJoinPool类的构造方法类创立线程池,而从代码构造上来看ForkJoinPool类继承自AbstractExecutorService抽象类。接下来,咱们看下ForkJoinPool类的构造方法。

public ForkJoinPool() {    this(Math.min(MAX_CAP, Runtime.getRuntime().availableProcessors()),         defaultForkJoinWorkerThreadFactory, null, false);} public ForkJoinPool(int parallelism) {    this(parallelism, defaultForkJoinWorkerThreadFactory, null, false);}public ForkJoinPool(int parallelism,                ForkJoinWorkerThreadFactory factory,                UncaughtExceptionHandler handler,                boolean asyncMode) {    this(checkParallelism(parallelism),         checkFactory(factory),         handler,         asyncMode ? FIFO_QUEUE : LIFO_QUEUE,         "ForkJoinPool-" + nextPoolId() + "-worker-");    checkPermission();}private ForkJoinPool(int parallelism,                 ForkJoinWorkerThreadFactory factory,                 UncaughtExceptionHandler handler,                 int mode,                 String workerNamePrefix) {    this.workerNamePrefix = workerNamePrefix;    this.factory = factory;    this.ueh = handler;    this.config = (parallelism & SMASK) | mode;    long np = (long)(-parallelism); // offset ctl counts    this.ctl = ((np << AC_SHIFT) & AC_MASK) | ((np << TC_SHIFT) & TC_MASK);}

通过查看源代码得悉,ForkJoinPool的构造方法,最终调用的是如下公有构造方法。

private ForkJoinPool(int parallelism,                 ForkJoinWorkerThreadFactory factory,                 UncaughtExceptionHandler handler,                 int mode,                 String workerNamePrefix) {    this.workerNamePrefix = workerNamePrefix;    this.factory = factory;    this.ueh = handler;    this.config = (parallelism & SMASK) | mode;    long np = (long)(-parallelism); // offset ctl counts    this.ctl = ((np << AC_SHIFT) & AC_MASK) | ((np << TC_SHIFT) & TC_MASK);}

其中,各参数的含意如下所示。

  • parallelism:并发级别。
  • factory:创立线程的工厂类对象。
  • handler:当线程池中的线程抛出未捕捉的异样时,对立应用UncaughtExceptionHandler对象解决。
  • mode:取值为FIFO_QUEUE或者LIFO_QUEUE。
  • workerNamePrefix:执行工作的线程名称的前缀。

当然,公有构造方法尽管是参数最多的一个办法,然而其不会间接对外办法,咱们能够应用如下形式创立线程池。

new ForkJoinPool();new ForkJoinPool(Runtime.getRuntime().availableProcessors());new ForkJoinPool(Runtime.getRuntime().availableProcessors(),             ForkJoinPool.defaultForkJoinWorkerThreadFactory,             null, true);

应用ScheduledThreadPoolExecutor类创立线程池

在Executors工具类中存在如下办法类创立线程池。

public static ScheduledExecutorService newSingleThreadScheduledExecutor() {    return new DelegatedScheduledExecutorService        (new ScheduledThreadPoolExecutor(1));}public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory) {    return new DelegatedScheduledExecutorService        (new ScheduledThreadPoolExecutor(1, threadFactory));}public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {    return new ScheduledThreadPoolExecutor(corePoolSize);}public static ScheduledExecutorService newScheduledThreadPool(        int corePoolSize, ThreadFactory threadFactory) {    return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);}

从源码来看,这几个办法实质上调用的都是ScheduledThreadPoolExecutor类的构造方法,ScheduledThreadPoolExecutor中存在的构造方法如下所示。

public ScheduledThreadPoolExecutor(int corePoolSize) {    super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,          new DelayedWorkQueue());}public ScheduledThreadPoolExecutor(int corePoolSize, ThreadFactory threadFactory) {    super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,          new DelayedWorkQueue(), threadFactory);}public ScheduledThreadPoolExecutor(int corePoolSize, RejectedExecutionHandler handler) {    super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,          new DelayedWorkQueue(), handler);}public ScheduledThreadPoolExecutor(int corePoolSize,ThreadFactory threadFactory, RejectedExecutionHandler handler) {    super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,          new DelayedWorkQueue(), threadFactory, handler);}

而从代码构造上看,ScheduledThreadPoolExecutor类继承自ThreadPoolExecutor类,实质上还是调用ThreadPoolExecutor类的构造方法,只不过此时传递的队列为DelayedWorkQueue。咱们能够间接调用ScheduledThreadPoolExecutor类的构造方法来创立线程池,例如以如下模式创立线程池。

new ScheduledThreadPoolExecutor(3)

好了,明天就到这儿吧,我是冰河,咱们下期见~~