ThreadPoolExecutor部分解析

1 ThreadPoolExecutor部分解析

Java构造线程的方式

  • 继承Thread
  • 实现Runnable
  • 实现Callable
  • 线程池方法(Java提供了构建线程池的方法)
    • Java提供的Executors可以创建(规范中不允许使用这种方式创建线程池)

在这里插入图片描述

线程池的参数

public ThreadPoolExecutor(
int corePoolSize, // 核心线程数
int maximumPoolSize,  // 最大线程数
long keepAliveTime,  // 最大空闲时间
TimeUnit unit,  // 时间单位
BlockingQueue<Runnable> workQueue,  // 阻塞队列
ThreadFactory threadFactory,  // 线程工厂
RejectedExecutionHandler handler // 拒绝策略
){
}

线程池的执行流程

在这里插入图片描述
饭店(线程池)
厨子(线程)
(这时来了好多顾客) 我们先是人多先排队(阻塞队列)
(当每天都来很多人我们想到)招厨子(创建最大线程数)
今日客满 (拒绝 - 拒绝策略)

线程池属性标识

// 1. 声明当前线程的状态  2.声明线程池中的线程数
// 高3位:线程池状态  低29位 : 线程池中的线程个数
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
private static final int COUNT_BITS = Integer.SIZE - 3;  // 值为29
private static final int COUNT_MASK = (1 << COUNT_BITS) - 1;  // 通过位运算得出最大容量

// runState is stored in the high-order bits  线程池状态  高3位
private static final int RUNNING    = -1 << COUNT_BITS; // 111 代表正常接收任务
private static final int SHUTDOWN   =  0 << COUNT_BITS; // 000 不接收新任务,但是内部还会处理阻塞队列中的任务,正在进行的任务也正常处理
private static final int STOP       =  1 << COUNT_BITS; // 001 不接收新任务,也不去处理阻塞队列中的任务,同时会中断正在执行的任务
private static final int TIDYING    =  2 << COUNT_BITS; // 010 过渡的状态,代表当前线程池即将Game Over
private static final int TERMINATED =  3 << COUNT_BITS; // 011 真正的结束了

// Packing and unpacking ctl
private static int runStateOf(int c)     { return c & ~COUNT_MASK; } // 得到线程池的状态
private static int workerCountOf(int c)  { return c & COUNT_MASK; }  // 得到现在线程池的线程数量
private static int ctlOf(int rs, int wc) { return rs | wc; }

在这里插入图片描述

线程池的execute方法执行

// execute方法
 if (command == null)
            throw new NullPointerException();
        // 拿到32位的int数值
        int c = ctl.get();
        // 获取 工作线程数 < 核心线程数
        if (workerCountOf(c) < corePoolSize) {
        	// 进入if 代表可以创建核心线程数
            if (addWorker(command, true))
                return;
            // 如果没进入if 代表创建核心线程数失败,重新获取 ctl
            c = ctl.get();
        }
        // 判断线程池是不是RUNNING,将任务添加到阻塞队列中
        if (isRunning(c) && workQueue.offer(command)) {
        	// 再次获得 ctl
            int recheck = ctl.get();
            // 再次判断是否是RUNNING , 如果不是RUNNING 移除任务
            if (! isRunning(recheck) && remove(command))
                reject(command); // 拒绝策略
            // 如果线程池处于RUNNING状态,BUT工作线程为0
            else if (workerCountOf(recheck) == 0)
            	// 阻塞队列有任务,但是没有工作线程,添加一个任务为空的工作线程处理阻塞队列中的任务
                addWorker(null, false);
        }
        // 创建非核心线程,处理任务
        else if (!addWorker(command, false))
            reject(command); // 拒绝策略
    }

通过上述源码,掌握了线程池的执行流程.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值