美文网首页
自定义Java线程池

自定义Java线程池

作者: 青春埋在这 | 来源:发表于2020-03-04 08:57 被阅读0次

    线程池创建的参数

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

    publicThreadPoolExecutor(int corePoolSize,

    int  maximumPoolSize,

    long  keepAliveTime,

    TimeUnitunit,

    BlockingQueue<Runnable>workQueue,

    ThreadFactorythreadFactory,

    RejectedExecutionHandlerhandler)

    corePoolSize: 线程池中线程的个数,最少的个数,即使是空闲的,也会存在

    maximumPoolSize: 线程池中允许的连接的最大个数

    keepAliveTime: corePoolSize之外的线程,在没有任务时,最大存活时间

    unit: keepAlveTime 的时间单位

    workQueue: 在任务还没有执行前,保存Runnable任务的地方,也就是待执行任务队列

    threadFactory: 线程工厂,可自定义线程生成的方式,可以自定义名字等等

    handler:在线程池和队列满的时候,如何处理新到来的任务

    jdk自带线程池的缺陷

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

    newCachedThreadPool

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

    publicstaticExecutorServicenewCachedThreadPool() {

    returnnewThreadPoolExecutor(0, Integer.MAX_VALUE,

    60L, TimeUnit.SECONDS,

    newSynchronousQueue());

        }

    newFixedThreadPool

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

    publicstaticExecutorServicenewFixedThreadPool(int nThreads) {

    returnnewThreadPoolExecutor(nThreads, nThreads,

    0L, TimeUnit.MILLISECONDS,

    newLinkedBlockingQueue());

        }

    自定义线程池

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

    /**

    * @author https://www.javastudy.cloud

    */

    publicclassThreadPoolTools{

    /** 线程池维护线程的最少数量 */

    privateintminPoolSize =10;

    /** 线程池维护线程的最大数量 */

    privateintmaxPoolSize =500;

    /** 线程池维护线程所允许的空闲时间 */

    privateintidleSeconds =1800;

    /** 线程池所使用的缓冲队列 */

    privateintqueueBlockSize =100;

    privateThreadPoolExecutor executor;

    publicThreadPoolTools() {

    this.executor =newThreadPoolExecutor(minPoolSize, maxPoolSize, idleSeconds,

    TimeUnit.SECONDS,/* 时间单位,秒 */

    newArrayBlockingQueue(queueBlockSize),

    newThreadPoolExecutor.CallerRunsPolicy());/* 重试添加当前加入失败的任务 */

        }

    publicvoidexecute(Runnable task) {

            executor.execute(task);

        }

    public Futuresubmit(Callable task){

    returnexecutor.submit(task);

        }

    }

    DEMO总评

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

    小编分类整理了许多java进阶学习材料和BAT面试题,需要资料的请转发此文章后再私聊小编回复【java】就能领取2019年java进阶学习资料和BAT面试题以及《Effective Java》(第3版)电子版书籍。

    相关文章

      网友评论

          本文标题:自定义Java线程池

          本文链接:https://www.haomeiwen.com/subject/ytjplhtx.html