自定义线程池拒绝策略 创建线程池的三种方法

在Java的高并发领域,线程池一直是一个无法回避的话题。有些童鞋一直在使用线程池,但是如何创建线程池只停留在使用Executors工具类的方式上。那么,创建线程池的方法有哪些呢?下面我们从创建线程池的源代码来深入分析一下有哪些创建线程池的方法。使用Executors工具类创建一...

在Java的高并发领域,线程池一直是一个无法回避的话题。有些童鞋一直在使用线程池,但是如何创建线程池只停留在使用Executors工具类的方式上。那么,创建线程池的方法有哪些呢?下面我们从创建线程池的源代码来深入分析一下有哪些创建线程池的方法。

使用Executors工具类创建一个线程池。

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

Executors.newCachedThreadPool:创建一个可缓存的线程池,如果线程池的大小超过了需要,可以灵活回收空闲线程,如果没有可回收线程,则新建线程Executors.newFixedThreadPool:创建一个定长的线程池,可以控制线程的最大并发数,超出的线程会在队列中等待Executors.newScheduledThreadPool:创建一个定长的线程池,支持定时、周期性的任务执行Executors.newSingleThreadExecutor:创建一个单线程化的线程池,使用一个唯一的工作线程执行任务,保证所有任务按照指定顺序(先入先出或者优先级)执行Executors.newSingleThreadScheduledExecutor:创建一个单线程化的线程池,支持定时、周期性的任务执行Executors.newWorkStealingPool:创建一个具有并行级别的work-stealing线程池

其中
executors . newworksealingpool方法是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 ***ximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {this(corePoolSize, ***ximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), defaultHandler);}public ThreadPoolExecutor(int corePoolSize,int ***ximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {this(corePoolSize, ***ximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, defaultHandler);}public ThreadPoolExecutor(int corePoolSize,int ***ximumPoolSize,long keepAliveTime, TimeUnit unit,BlockingQueue<Runnable> workQueue,RejectedExecutionHandler handler) {this(corePoolSize, ***ximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), handler);}public ThreadPoolExecutor(int corePoolSize,int ***ximumPoolSize,long keepAliveTime,TimeUnit unit, BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler) {if (corePoolSize < 0 ||***ximumPoolSize <= 0 ||***ximumPoolSize < 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.***ximumPoolSize = ***ximumPoolSize;this.workQueue = workQueue;this.keepAliveTime = unit.toNanos(keepAliveTime);this.threadFactory = threadFactory;this.handler = handler;}

根据ThreadPoolExecutor类构造方法的源代码,最终调用创建线程池的构造方法如下。

public ThreadPoolExecutor(int corePoolSize, int ***ximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {if (corePoolSize < 0 ||***ximumPoolSize <= 0 ||***ximumPoolSize < 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.***ximumPoolSize = ***ximumPoolSize;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 paralleli***) {return new ForkJoinPool(paralleli***, 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 paralleli***) {this(paralleli***, defaultForkJoinWorkerThreadFactory, null, false);}public ForkJoinPool(int paralleli***,ForkJoinWorkerThreadFactory factory,UncaughtExceptionHandler handler,boolean asyncMode) {this(checkParalleli***(paralleli***), checkFactory(factory), handler, asyncMode ? FIFO_QUEUE : LIFO_QUEUE, "ForkJoinPool-" + nextPoolId() + "-worker-");checkPermission();}private ForkJoinPool(int paralleli***, ForkJoinWorkerThreadFactory factory, UncaughtExceptionHandler handler, int mode, String workerNamePrefix) {this.workerNamePrefix = workerNamePrefix;this.factory = factory;this.ueh = handler;this.config = (paralleli*** & SMASK) | mode;long np = (long)(-paralleli***); // offset ctl countsthis.ctl = ((np << AC_SHIFT) & AC_MASK) | ((np << TC_SHIFT) & TC_MASK);}

通过看源代码,我们知道ForkJoinPool的构造方法最后调用了下面的私有构造方法。

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

其中,各参数的含义如下。

paralleli***:并发级别。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类继承了threadpooleexecutor类,本质上是调用threadpooleexecutor类的构造方法,只是此时传递的队列是DelayedWorkQueue。我们可以直接调用ScheduledThreadPoolExecutor类的构造函数来创建一个线程池,比如用下面的形式创建一个线程池。

new ScheduledThreadPoolExecutor(3)

本文来自我要无比强大投稿,不代表舒华文档立场,如若转载,请注明出处:https://www.chinashuhua.cn/24/545364.html

打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
() 0
上一篇 05-13
下一篇 05-13

相关推荐

  • 家电营销策划推广方案,家电营销策略技巧_1

    在市场的寒潮中,很多企业都在推行精细化管理方法。那么在当前的互联网时代,在应用场景和渠道多元化的前提下,家电企业应该如何提升管理水平呢?销售智慧卖汇智的目标是为家电行业提供专业的互联网工具和互联网解决方案。卖汇智将继续根据最新的商业模式,为家电行业的朋友们

    2023-07-28 04:59:01
    1031 0
  • 广告营销策略有哪些 最受用的9大策略

    广告的基石是那些天才的想法。创造性的想法来自生活的各个方面——它们能迅速改变我们的思维方式。在时间的长河中,一些营销活动不仅在当时引起了巨大的口碑效应,也极大地促进了产品的销售,而且持续时间很长,潜移默化地融入了社会文化生活,甚至影响了未来世界的营销规则。

    2023-07-28 02:49:02
    549 0
  • 什么是ugc内容,ugc内容的运营策略

    社区是产生UGC内容的最佳渠道互联网早期,在基于PC的搜索时代,用户之间的交互多是一对一、一对多的形式,比如张贴在贴吧的评论和回复、天涯社区的消息交流等。随着移动互联网的发展,原本零碎内容的UCG形式逐渐被淘汰,运营商利用微信社区的形式聚集用户进行点对点互动。这有

    2023-07-28 02:23:01
    197 0
  • 商业计划书销售策略怎么写 附完整的商业计划书

    商业计划有多重要?如果你还是不明白,那就先去看看:为什么听了那么多好话也拿不到钱?如果你拥有一切,你所需要的只是落地的鼓风机。然后看一看商业计划书的门道,享受一次手把手的融资教学。一、商业计划书的门道我们先梳理一下商业计划书的框架:1。大纲:写在最后,放在最前

    2023-07-27 15:19:01
    283 0

评论列表

联系我们

在线咨询: QQ交谈

邮件:admin@qq.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信