设为首页 加入收藏

TOP

深入浅出线程池(五)
2023-09-23 15:43:23 】 浏览:174
Tags:程池
lowCoreThreadTimeOut || wc > corePoolSize; ? if ((wc > maximumPoolSize || (timed && timedOut)) && (wc > 1 || workQueue.isEmpty())) { if (compareAndDecrementWorkerCount(c)) //若线程存活时间超时,则CAS减去线程数量 return null; continue; } ? try { Runnable r = timed ? workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) : //允许超时回收则阻塞等待 workQueue.take(); //不允许则直接获取,没有就返回null if (r != null) return r; timedOut = true; } catch (InterruptedException retry) { timedOut = false; } } }

小结:getTask()方法主要功能;

  1. 实际在缓存队列中获取待执行的任务;

  2. 在这里管理线程是否要阻塞等待,控制线程的数量;

2.1.3.6、清理工作

  private void processWorkerExit(Worker w, boolean completedAbruptly) {
        if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
            decrementWorkerCount();
?
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            completedTaskCount += w.completedTasks;
            workers.remove(w);          //移除执行完成的线程
        } finally {
            mainLock.unlock();
        }
?
        tryTerminate();     //每次回收完一个线程后都尝试终止线程池
?
        int c = ctl.get();
        if (runStateLessThan(c, STOP)) {    //到这里说明线程池没有终止
            if (!completedAbruptly) {
                int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
                if (min == 0 && ! workQueue.isEmpty())
                    min = 1;
                if (workerCountOf(c) >= min)
                    return; // replacement not needed
            }
            addWorker(null, false);     //异常终止线程的话,需要在常见一个线程
        }
    }

小结:processWorkerExit()方法主要功能;

  1. 真实完成线程池线程的回收;

  2. 调用尝试终止线程池;

  3. 保证线程池正常运行;

2.1.3.7、尝试终止线程池

    final void tryTerminate() {
        for (;;) {
            int c = ctl.get();
            
            //若线程池正在执行、线程池已终止、线程池还需要执行缓存队列中的任务时,返回
            if (isRunning(c) ||
                runStateAtLeast(c, TIDYING) ||
                (runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))
                return;
                
            //执行到这里,线程池为SHUTDOWN且无待执行任务 或 STOP 状态
            if (workerCountOf(c) != 0) {
                interruptIdleWorkers(ONLY_ONE);     //只中断一个线程
                return;
            }
?
            //执行到这里,线程池已经没有可用线程了,可以终止了
            final ReentrantLock mainLock = this.mainLock;
            mainLock.lock();
            try {
                if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {  //CAS设置线程池终止
                    try {
                        terminated();   //执行钩子方法
                    } finally {
                        ctl.set(ctlOf(TERMINATED, 0));  //这里将线程池设为终态
                        termination.signalAll();
                    }
                    return;
                }
            } finally {
                mainLock.unlock();
            }
            // else retry on failed CAS
        }
    }

小结:tryTerminate()方法主要功能;

  1. 实际尝试终止线程池;

  2. 终止成功则调用钩子方法,并且将线程池置为终态。

2.2、JAVA线程池总结

以上通过对JAVA线程池的具体分析我们可以看出,虽然流程看似复杂,但其实有很多内容都是状态重复校验、线程安全的保证等内容,其主要的功能与我们前面所提出的设计功能一致,只是额外增加了一些扩展,下面我们简单整理下线程池的功能;

2.2.1、主要功能

  1. 线程数量及存活时间的管理;

  2. 待处理任务的存储功能;

  3. 线程复用机制功能;

  4. 任务超量的拒绝功能;

2.2.2、扩展功能

  1. 简单的执行结果统计功能;

  2. 提供线程执行异常处理机制;

  3. 执行前后处理流程自定义;

  4. 提供线程创建方式的自定义;

2.2.3、流程总结

以上通过对JAVA线程池任务提交流程的分析我们可以看出,线程池执行的简单流程如下图所示;

2.3、JAVA线程池使用

线程池基本使用验证上述流程:

   public static void main(String[] args) throws Exception {
        
        //创建线程池
       ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
               5, 10, 100, TimeUnit.SECONDS, new ArrayBlockingQueue(5));
        
        //加入4个任务,小于核心线程,应该只有4个核心线程,队列为0
        for (int i = 0; i < 4; i++) {
            threadPoolExecutor.submit(new MyRunnable());
        }
        System.out.println("worker count = " + threadPoolExecutor.getPoolSize());   //worker count = 4
        System.out.println("queue size = " + threadPoolExecutor.getQueue().size()); //queue size = 0
        
        //再加4个任务,超过核心线程,但是没有超过核心线程 + 缓存队列容量,应该5个核心线程,队列为3
        for (int i = 0; i < 4; i++) {
            threadPoolExecutor.submit(new MyRunnable());
        }
        System.out.println("worker count = " + threadPoolExecutor.getPoolSize());   //worker count = 5
        System.out.println("queue siz
首页 上一页 2 3 4 5 6 下一页 尾页 5/6/6
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇2023最全Java面试题及答案汇总 下一篇结对编程队友个人项目互评

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目