zoukankan      html  css  js  c++  java
  • 《java.util.concurrent 包源码阅读》13 线程池系列之ThreadPoolExecutor 第三部分

    这一部分来说说线程池如何进行状态控制,即线程池的开启和关闭。

    先来说说线程池的开启,这部分来看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.corePoolSize = corePoolSize;
            this.maximumPoolSize = maximumPoolSize;
            this.workQueue = workQueue;
            this.keepAliveTime = unit.toNanos(keepAliveTime);
            this.threadFactory = threadFactory;
            this.handler = handler;
        }

    可以看到,尽管设定了corePoolSize,也就是Worker线程的数量,但是线程池开启的时候,默认是没有创建这些Worker线程的,但是ThreadPoolExecutor提供了prestartAllCoreThreads方法来开启所有的预设的Worker线程,以及prestartCoreThread尝试开启一个预设的Worker线程。

    这里重点说说handler,也就是RejectedExecutionHandler,拒绝任务的处理类,ThreadPoolExecutor提供四种策略:

    1. CallerRunsPolicy

    该策略会在ThreadPoolExecutor没有关闭的情况,依旧运行任务

    2. AbortPolicy

    该策略会抛出一个RejectedExecutionException

    3. DiscardPolicy

    该策略直接忽略该任务,不会有任何动作

    4. DiscardOldestPolicy

    该策略会在ThreadPoolExecutor没有关闭的情况,丢弃下一个将要执行的任务,把该任务加入到执行队列。

    接下来说说关闭,ThreadPoolExecutor提供了shutdown和shutdownNow两种方式,从字面上就能看出区别,后者会尝试结束正在运行的任务。

    先来看shutdown:

        public void shutdown() {
            final ReentrantLock mainLock = this.mainLock;
            mainLock.lock();
            try {
                checkShutdownAccess();
                advanceRunState(SHUTDOWN);
                interruptIdleWorkers();
                onShutdown(); // ScheduledThreadPoolExecutor的回调方法
            } finally {
                mainLock.unlock();
            }
            tryTerminate();
        }


    再看shutdownNow:

        public List<Runnable> shutdownNow() {
            List<Runnable> tasks;
            final ReentrantLock mainLock = this.mainLock;
            mainLock.lock();
            try {
                checkShutdownAccess();
                advanceRunState(STOP);
                interruptWorkers();
                tasks = drainQueue();
            } finally {
                mainLock.unlock();
            }
            tryTerminate();
            return tasks;
        }

    两个方法的代码非常相似,区别在于:

    1. shutdownNow的状态设置为STOP,shutdown的状态是SHUTDOWN

    2. shutdownNow会中断所有线程,也就是所有任务,而shutdown仅仅中断空闲线程,不会影响正在执行的任务。

    3. shutdownNow会导出未执行的任务。

    两个方法都用到的checkShutdownAccess方法主要是检查方法调用者是否有权限中断Worker线程。

    advanceRunState方法用于设定线程的状态,如果状态值大于等于该状态值则会返回。关于状态值参看 《java.util.concurrent 包源码阅读》11 线程池系列之ThreadPoolExecutor 第一部分。

    关于interruptIdleWorkersinterruptWorkers,在上一篇文章曾经说过Worker线程具备锁的功能,因此可以通过tryLock来判断Worker线程是否处于空闲状态,这是两个方法的区别所在。

    这一部分写的有些凌乱,各位见谅。

  • 相关阅读:
    django class类即视图类添加装饰器的几种方法
    django 如何在HMTL中使用媒体media_url
    django 对models中上传的文件或图片改名
    常用工具链接网址
    verifycode验证码模版
    shell 一些常用命令
    用 openresty 编写 lua
    centos7 安装python虚拟环境
    django url配置-反向解析-视图函数-HttpRequest对象-HttpResponse对象-cookies-session-redis缓存session
    PWN题搭建
  • 原文地址:https://www.cnblogs.com/wanly3643/p/3924617.html
Copyright © 2011-2022 走看看