zoukankan      html  css  js  c++  java
  • 线程池的实现原理

    runState   线程池的运行状态                        

    running:表明线程池在运行当中,可以接受新的任务,也可以处理阻塞队列中的任务。

    shutdown:不可以接受新的任务了,但是还可以执行阻塞队列中的任务。

    stop:不可接收新任务,不可执行阻塞队列里的任务了,并且尝试终止所有在运行任务。

    tidying:所有任务已经终止,执行terminated()

    terminated:线程池完全关闭

    在ThreadPoolExecutor的构造方法中,定义了线程池的核心线程数,最大线程数,过期时间,时间单位,阻塞队列,创建线程的工厂,拒绝策略。下面来看看默认的线程工厂,它到底是如何创建新的线程的。

    DefaultThreadFactory实现了ThreadFactory接口,

    在DefaultThreadFactory构造方法中确定线程的命名前缀,之后每创建一个线程,poolNumber不变,threadNumber++,并设置线程是否是Deamon线程、线程的优先级等。

     

    何时调用newThread()方法呢?Worker是对提交任务的封装,如果调用Worker的构造方法,就会创建一个新的线程中去执行任务。

    ||左边为真,右边就不再执行了,也就是如果task不为null,就运行firstTask,如果为null,就从阻塞队列获取任务执行。

    while (task != null || (task = getTask()) != null)

     

    现在我们来看看线程池的运行原理:当提交任务到线程池中,会调用execute方法

    如果当前线程数比核心线程数小,那么就添加一个Worker(也就是创建一个新的线程,去处理这个任务),并直接return。如果已经达到核心线程数,那么新来的任务会插入到阻塞队列中,也就是workQueue.offer(command).如果队列也满了,还有任务到来的话,那么就继续创建新的线程。如果创建新的线程时池子已经达到最大线程数,就采取拒绝策略。

    添加Worker的方法:

     

    在该方法中会调用new Worker(firstTask)构造函数,创建线程并运行此任务。

    如何关闭线程池呢?

    shutdown()方法会停止接受任务,但是已经提交的任务可以继续执行。该方面将线程池状态改为shutdown,然后中断所有空闲的线程。

    在中断所有空闲线程的方法中,有一个tryLock(),如果线程正在执行,是持有锁的,所以tryLock()获取不到,也就不会中断了。

    shutdownNow()方法将线程池状态设置成stop,不能再提交任务,已经提交但未执行的任务不能运行,正在运行的任务可继续运行,但会被中断(尝试终止所有在运行任务),返回已经提交但未执行的任务。

    这里会中断所有的线程

    最后都要调用tryTerminate()方法,尝试彻底关闭线程池,会先用CAS将线程池状态改为tidying,最后调用terminated()方法。

  • 相关阅读:
    git, tornado 小计
    算法小计-列表排列
    CMDB小计1
    linux 中mysql的主从复制
    SQL语句的种类
    mysql的结构,段页区,及客户端命令
    mysql的程序结构,实例, 及mysql的多实例
    在linux中操作mysql误删root用户的应对方法
    MySQL面试
    linux下载安装mysal
  • 原文地址:https://www.cnblogs.com/james111/p/7382619.html
Copyright © 2011-2022 走看看