美文网首页
JUC(二) | 线程池浅谈

JUC(二) | 线程池浅谈

作者: 采风JS | 来源:发表于2017-07-15 19:22 被阅读0次

前面简单学习了JUC同步辅助类,今天一起走进线程池的美妙新世界。

一、从新建线程池谈起

    public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }    
    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
    }

  • 类的区别
    Executor是执行者接口,通过execute方法执行Runnable任务;
    ExecutorService是执行者服务接口,通过submit将任务提交给Executor执行;
    ThreadPoolExecutor是真正的实现类;
    Executors是静态工厂类,可以返回ExecutorService等;

  • 参数概念
    corePoolSize : 线程池中允许同时运行的线程数;
    maximumPoolSize : 线程池中允许创建的最大线程数;
    keepAliveTime:线程池空闲后,超过此时间的线程会被终止;
    workQueue :线程任务阻塞队列;
    defaultThreadFactory : 返回线程工厂,线程池中的线程均是由线程工厂创建;
    defaultHandler:任务添加到线程池中,线程池拒绝时采取的策略;

二、以execute方法为重

    public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
        int c = ctl.get();
        //策略一:线程池中运行数量小于corePoolSize时,直接新建任务
        if (workerCountOf(c) < corePoolSize) {
            if (addWorker(command, true))
                return;
            c = ctl.get();
        }
        //策略二:线程池中大于等于corePoolSize时,且线程池状态允许时,将任务添加到阻塞队列中
        if (isRunning(c) && workQueue.offer(command)) {
            int recheck = ctl.get();
            if (! isRunning(recheck) && remove(command))
                reject(command);
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }
        //策略三:线程池中大于等于corePoolSize时,且线程池状态不允许时,直接新建任务
        else if (!addWorker(command, false))
            reject(command);
    }
  • addWork源码解读
  • 上面代码中多次谈到线程池状态及拒绝策略,下一步深入理解

三、线程池状态及转换

  • 与线程的五种状态不同,线程池的五种状态及其转换如下图所示:
线程池的状态.png

Running:能接受新任务,且处理已添加任务;(对应于isRunning检测)
ShutDown:不能接受新任务,可处理已添加任务;
Stop:不能接受新任务,且会中断已处理任务;
Tidying:所有任务已经终止;
Terminated:Tidying状态后,执行钩子函数terminate,进入此状态;

四、拒绝策略

AbortPolicy:当任务添加到线程池中被拒绝时,它将抛出 RejectedExecutionException 异常;
CallerRunsPolicy:当任务添加到线程池中被拒绝时,会在线程池当前正在运行的Thread线程池中处理被拒绝的任务;
DiscardOldestPolicy:当任务添加到线程池中被拒绝时,线程池会放弃等待队列中最旧的未处理任务,然后将被拒绝的任务添加到等待队列中;
DiscardPolicy:当任务添加到线程池中被拒绝时,线程池将丢弃被拒绝的任务;

相关文章

  • JUC(二) | 线程池浅谈

    前面简单学习了JUC同步辅助类,今天一起走进线程池的美妙新世界。 一、从新建线程池谈起 类的区别Executor是...

  • 多线程juc线程池

    java_basic juc线程池 创建线程池 handler是线程池拒绝策略 排队策略 线程池状态 RUNNIN...

  • JUC 线程池

    概述 线程池的作用:节省资源、提升响应、削峰限流、管理线程 ThreadPoolExecutor的核心参数:cor...

  • 线程池-核心参数-03

    当我们使用 callable 接口实现线程时,常会和 juc 下面的线程池一起使用。这里主要看看 线程池的核心参数...

  • Java 线程池创建、使用、停止

    JUC 已经提供了一些现成的线程池给开发者使用,但是这些线程池或多或少不能满足具体的业务开发需求,所以在使用线程池...

  • 博客系列-2019年时间轴

    2019年 JUC线程池服务ExecutorService接口实现源码分析 Github Page:http://...

  • JUC线程池(4):线程池状态

    我们都知道,线程有5种状态:新建状态,就绪状态,运行状态,阻塞状态,死亡状态。线程池也有5种状态;然而,线程池不同...

  • JUC线程池(1):线程池架构

    线程池架构图 1.Executor 它是一个接口,用来执行任务的。准确来说,Executor提供了execute(...

  • JUC线程池(7):线程池总结

    1、前言 之前被人问懵了,其实原理很简单: 任务被提交到线程池时,如果线程数小于 corePoolSize,先创建...

  • JUC之线程池

    线程池 线程池做的工作主要是控制运行的线程的数量 ,处理过程中将任务加入队列 ,然后在线程创建后启动这些任务, 如...

网友评论

      本文标题:JUC(二) | 线程池浅谈

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