博客
关于我
Java线程池源码及原理
阅读量:445 次
发布时间:2019-03-06

本文共 1402 字,大约阅读时间需要 4 分钟。

线程池的状态与源码分析

1. 线程池的状态

线程池的运行状态通过 ctl 中的高3位来表示,共有5种状态:

  • RUNNING:高3位为111,线程池接收新任务。
  • SHUTDOWN:高3位为000,线程池停止接收新任务。
  • STOP:高3位为001,线程池完全终止。
  • TIDYING:高3位为010,所有任务已终止。
  • TERMINATED:高3位为011,terminated() 方法已执行完成。

线程池的核心池大小为 corePoolSize,最大允许线程数为 maximumPoolSize,线程活跃时间为 keepAliveTime


2. 任务的执行

线程池的任务执行流程分为几个关键步骤:

  • execute(Runnable command)

    • 检查当前运行线程数是否小于核心池大小 corePoolSize,如果是,则直接调用 addWorker
    • 否则,将任务添加到工作队列 workQueue 中。
    • 如果工作队列已满,则尝试再次调用 addWorker
  • addWorker(Runnable firstTask, boolean core)

    • 判断线程池状态。
    • 通过 CAS 操作增加运行线程数。
    • 创建 Worker 实例,线程通过 ThreadFactory 构造,并将 Workerrun() 方法设置为线程的初始目标。
    • 启动线程。
  • runWorker(Worker w)

    • 循环调用 getTask() 获取任务。
    • 执行任务前调用 beforeExecute 方法。
    • 执行任务后调用 afterExecute 方法。
  • getTask()

    • 通过 ctl.get() 获取当前线程池状态 c
    • 根据 runStateOf(c) 判断线程池状态:
      • 如果是 SHUTDOWNSTOP 且工作队列为空,减少运行线程数并返回 null
    • 获取当前运行线程数 wc
    • 如果是核心线程允许超时或线程数量超过最大值且工作队列为空,尝试减少运行线程数并返回 null
    • 从工作队列中获取任务。如果任务存在,返回任务;否则,等待队列中的任务。

  • 3. 任务执行,带返回值的

    线程池支持带返回值的任务执行,主要通过 Future 实现。具体方法如下:

    public Future
    submit(Callable
    task) { if (task == null) throw new NullPointerException(); RunnableFuture
    ftask = newTaskFor(task); execute(ftask); return ftask;}public Future
    submit(Runnable task) { if (task == null) throw new NullPointerException(); RunnableFuture
    ftask = newTaskFor(task, null); execute(ftask); return ftask;}
    • 将任务封装到 RunnableFuture 中,并通过 execute 方法提交执行。
    • RunnableFuture 实现了 Future 接口,可以用来获取任务的执行结果。

    参考资料

    转载地址:http://boufz.baihongyu.com/

    你可能感兴趣的文章
    PHP XSS攻击防范--如何过滤用户输入
    查看>>
    php zookeeper实现分布式锁
    查看>>
    PHP 中 this,self,parent 的区别、用法
    查看>>
    PHP 中如何高效地处理大规模数据的排序?
    查看>>
    PHP 之ftp客户端类封装实现
    查看>>
    php 代码改进
    查看>>
    php 代码混淆
    查看>>
    PHP 使用 $_SERVER['PHP_SELF'] 获取当前页面地址及其安全性问题
    查看>>
    Redis系列之如何避免缓存击穿
    查看>>
    php 内存分析
    查看>>
    PHP 函数名前面加&
    查看>>
    redis报错
    查看>>
    php 删除包含某一字符的数组元素
    查看>>
    Redis学习总结(19)——Redis 5种集群方式对比
    查看>>
    php 反射
    查看>>
    php 处理 大并发
    查看>>
    php 大文件上传
    查看>>
    php 子进程监听消息,swoole学习笔记之多线程端口监听问题记录 多进程epoll模式...
    查看>>
    PHP 学习笔记 (四)
    查看>>
    Redis入门概述
    查看>>