线程池ThreadPoolExecutor剖析

一)Java构建线程的方式

1. 继承Thread

2. 实现Runnable

3. 实现Callable

4. 线程池实现(Java提供了构建线程池的方式)

        java提供了Executor可以去创建(规范中不允许使用这种方式创建线程池,这种方式对线程的控制粒度比较低),建议  new ThreadPoolExecutor()

二) 线程池的7个参数

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

三) 线程池的执行流程  

对图的一个说明:

1. 当有任务时,提交任务,在线程池中查看是否有核心线程,如果有,则执行该任务,如果没有,则把该任务放到阻塞队列中

2. 如果阻塞队列没满,则放到阻塞队列中排队,如果满了,则看线程池中的工作线程数量是否为最大线程数,如果不是,则创建非核心线程,如果是,则采取拒绝策略

四) 线程池属性标识

//  AtomicInteger 是 int类型的数据,声明线程池的状态,声明线程池中的线程数 
//   高三位是线程池的状态,低三位是线程池的个数   
    private final AtomicInteger ctl;   
    private static final int COUNT_BITS = 29; //  Integer.size   
    private static final int CAPACITY = 536870911; //  最大容量 

    // 以下是【线程池的状态】
    private static final int RUNNING = -536870912;   //111代表正常接收任务
    private static final int SHUTDOWN = 0;  //000代表线程池为shutdown的状态,不接收新的任务,但是内部还是会处理队列中的任务,正在进行的任务正常处理
    private static final int STOP = 536870912; //  001 代表线程池为stop状态。不接收新的任务,也不去处理阻塞队列中的任务,同时也会中断正在执行中的任务
    private static final int TIDYING = 1073741824; // 010 代表线程池是一个过渡状态,代表当前线程池即将over
    private static final int TERMINATED = 1610612736;// 011 代表线程池状态为over
    
    //  得到线程池的状态
    private static int runStateOf(int var0) {return var0 & -536870912;}
    //  得到当前线程池的线程数量
    private static int workerCountOf(int var0) { return var0 & 536870911;}

线程池转态变化

 五)线程池的execute方法执行

public void execute(Runnable var1) {
        //  健壮性的判断
        if (var1 == null) {
            throw new NullPointerException();
        } else {
        //  拿到32位的int
            int var2 = this.ctl.get();
        //  获取 【工作线程数】< 核心线程数  
            if (workerCountOf(var2) < this.corePoolSize) {
                // 可以创建 【核心】 线程数
                if (this.addWorker(var1, true)) {
                    return;
                }
                //  代表创建核心线程数失败,重新获取ctl
                var2 = this.ctl.get();
            }
        //  判断线程池是否是running转态 (因为要看是否接收新任务)
        //  将任务放到阻塞队列中
            if (isRunning(var2) && this.workQueue.offer(var1)) {
                //  再次获取ctl
                int var3 = this.ctl.get();
                //  再次判断是否是running状态   如果不是running,移除任务
                if (!isRunning(var3) && this.remove(var1)) {
                    this.reject(var1);   //  拒绝策略
                           //   获取线程池个数 
                        //  如果线程池处于running状态,但是工作线程为0
                } else if (workerCountOf(var3) == 0) {
            //  阻塞队列有任务,但是没有工作线程,添加一个任务为空的工作线程处理阻塞队列中的任务
                    this.addWorker((Runnable)null, false);
                }
            //  创建非核心线程处理任务
            } else if (!this.addWorker(var1, false)) {
                //  拒绝
                this.reject(var1);
            }
        }
    }

查看addWorker方法

 private boolean addWorker(Runnable var1, boolean var2) {
        while(true) {
            //  获取ctl
            int var3 = this.ctl.get();
            //  获取线程池状态
            int var4 = runStateOf(var3);
            //  除了running都有可能
            if (var4 >= 0 && 
                //  shutdown      任务为空         阻塞队列为空
                (var4 != 0 || var1 != null || this.workQueue.isEmpty())) {
                 //   创建工作线程失败
                return false;
            }

            while(true) {
                int var5 = workerCountOf(var3);
                //  如果已经达到了线程池的最大容量,则不去创建了
                //  判断是否超过核心线程
                if (var5 >= 536870911 || var5 >= (var2 ? this.corePoolSize : this.maximumPoolSize)) {
                    return false;
                }

                //   将工作线程数+1  ,采用CAS的方式
                if (this.compareAndIncrementWorkerCount(var3)) {
                    boolean var18 = false;
                    boolean var19 = false;
                    //   worker就是工作线程
                    ThreadPoolExecutor.Worker var20 = null;

                    try {
                        var20 = new ThreadPoolExecutor.Worker(var1);
                        //  从工作线程中获取thread
                        Thread var6 = var20.thread;
                        if (var6 != null) {
                            //  获取线程池的全局锁,防止其他线程干掉这个线程池
                            ReentrantLock var7 = this.mainLock;
                            var7.lock();

                            try {
                                int var8 = runStateOf(this.ctl.get());
                                if (var8 < 0 || var8 == 0 && var1 == null) {
                                    if (var6.isAlive()) {
                                        throw new IllegalThreadStateException();
                                    }

                                    this.workers.add(var20);
                                    int var9 = this.workers.size();
                                    if (var9 > this.largestPoolSize) {
                                        this.largestPoolSize = var9;
                                    }

                                    var19 = true;
                                }
                            } finally {
                                var7.unlock();
                            }

                            if (var19) {
                                var6.start();
                                var18 = true;
                            }
                        }
                    } finally {
                        if (!var18) {
                            this.addWorkerFailed(var20);
                        }

                    }

                    return var18;
                }

                var3 = this.ctl.get();
                if (runStateOf(var3) != var4) {
                    break;
                }
            }
        }
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值