前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >java基础|自定义java线程池

java基础|自定义java线程池

作者头像
微笑的小小刀
发布2019-12-18 11:10:36
1.2K0
发布2019-12-18 11:10:36
举报
文章被收录于专栏:java技术大本营java技术大本营

线程池创建的参数

在创建线程的各种方式中我们有讲到过通过创建线程池来完成异步操作,但实际上jdk提供的Executors来创建线程池都还有些缺陷,线程池有以下几个参数: 代码节选自源码ThreadPoolExecutor.java的构造函数

代码语言:javascript
复制
   public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler)

corePoolSize: 线程池中线程的个数,最少的个数,即使是空闲的,也会存在 maximumPoolSize: 线程池中允许的连接的最大个数 keepAliveTime: corePoolSize之外的线程,在没有任务时,最大存活时间 unit: keepAlveTime 的时间单位 workQueue: 在任务还没有执行前,保存Runnable任务的地方,也就是待执行任务队列 threadFactory: 线程工厂,可自定义线程生成的方式,可以自定义名字等等 handler:在线程池和队列满的时候,如何处理新到来的任务

jdk自带线程池的缺陷

自带的线程池主要是通过Executors来初始化.

newCachedThreadPool

通过Executors.newCachedThreadPool()初始化的线程池如下文所示,可以看到maximumPoolSize的值是Integer.MAX_VALUE,这就意味着线程池里面的线程没有上限,会一直新建到OOM.

代码语言:javascript
复制
public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

newFixedThreadPool

通过Executors.newFixedThreadPool新建的线程池,我们可以看到workQueue这个参数传的是new LinkedBlockingQueue,这个队列没有设置大小,就会导致新任务会一直往里添加,直到OOM

代码语言:javascript
复制
public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

自定义线程池

通过对自带的线程池的分析,我们知道自定义的线程池主要是对池子的最大数量和等待队列的最大数量做好限制,当然还有自定义的失败策略(以后单写个DEMO讲)代码如下:

代码语言:javascript
复制
/**
 * @author https://www.javastudy.cloud
 */
public class ThreadPoolTools {

    /** 线程池维护线程的最少数量 */
    private int minPoolSize = 10;

    /** 线程池维护线程的最大数量 */
    private int maxPoolSize = 500;

    /** 线程池维护线程所允许的空闲时间 */
    private int idleSeconds = 1800;

    /** 线程池所使用的缓冲队列 */
    private int queueBlockSize = 100;

    private ThreadPoolExecutor executor;

    public ThreadPoolTools() {
        this.executor = new ThreadPoolExecutor(minPoolSize, maxPoolSize, idleSeconds,
                TimeUnit.SECONDS, /* 时间单位,秒 */
                new ArrayBlockingQueue<Runnable>(queueBlockSize),
                new ThreadPoolExecutor.CallerRunsPolicy()); /* 重试添加当前加入失败的任务 */
    }

    public void execute(Runnable task) {
        executor.execute(task);
    }

    public <T> Future<T> submit(Callable<T> task){
        return executor.submit(task);
    }
}

DEMO总评

线程池的使用在实际开发中用到的还是挺多的,在小型开发中使用系统自带的线程池是没问题的,但有时候在生产环境中,特别是同步一些东西的时候,量级比较大,这时候使用系统自带的线程池难免会有些问题,这时候就需要自定义的线程池了,加油吧,少年!

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-12-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 java技术大本营 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • jdk自带线程池的缺陷
    • newCachedThreadPool
      • newFixedThreadPool
      • 自定义线程池
      • DEMO总评
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档