并发编程(十)线程池核心原理与源码剖析

简介: 并发编程(十)线程池核心原理与源码剖析

线程池核心原理与源码剖析

线程池的状态

  • RUNNING:能够接收新任务,以及对新加的任务进行任务,创建线程池的默认状态。
  • SHUTDOWN:不再接收新任务,会继续处理完正在处理的任务和阻塞队列中的任务,调用shutdown()更改状态。
  • STOP:不在接收新任务,不再处理阻塞队列中的任务,并中断线程池中正在处理的任务,调用shutdownNow()更改状态。
  • TINY: SHUTDOWN状态时,所有任务已中止,阻塞队列中的任务数量为0;STOP状态时,所有任务已中止
  • TERMINATED:线程池彻底终止。

线程池的重要属性&方法

private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
private static final int COUNT_BITS = Integer.SIZE - 3;
private static final int CAPACITY   = (1 << COUNT_BITS) - 1;
private static int runStateOf(int c)     { return c & ~CAPACITY; }
private static int workerCountOf(int c)  { return c & CAPACITY; }
private static int ctlOf(int rs, int wc) { return rs | wc; }
  • ctl:高三位记录线程池的状态,低29位保存线程池的线程数量
  • COUNT_BITS:低29位
  • CAPACITY:线程池的线程容量,2^29-1
  • runStateOf:获取运行状态
  • workerCountOf:获取活动线程的数量
  • ctlOf:得出运行状态和活动线程的值,新的ctl

线程池的具体实现

Executor具体实现.png

  • ThreadPoolExecutor:默认线程池
  • ScheduledThreadPoolExecutor:定时任务线程池

线程池的创建

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler)
  • corePoolSize:核心线程数,当提交一个任务时,线程池会创建一个新线程处理任务,直到线程数量等于corePoolSize,后续再提交线程时会将线程放入阻塞队列。
  • maximumPoolSize:最大线程数,当阻塞队列已满,此时再提交任务时,会创建非核心线程进行处理,线程池中创建的线程数量必须小于maximumPoolSize
  • keepAliveTime:线程空闲时间,当线程池中的线程数量大于corePoolSize(存在非核心线程),如果此时没有新的任务提交,非核心线程不会立即销毁,而是会等待,直到等待时间超过了keepAliveTime
  • unit:线程空闲的时间单位
  • workQueue:用来保存等待被执行的任务的阻塞队列,JDK中提供了以下阻塞队列
  • ArrayBlockingQueue:基于数组结构的有界阻塞队列,按FIFO排序任务
  • LinkedBlockingQuene:基于链表结构的有界阻塞队列,按FIFO排序任务,吞吐量通常要高于ArrayBlockingQuene
  • SynchronousQuene:一个不存储元素的阻塞队列,每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态,吞吐量通常要高于LinkedBlockingQuene
  • PriorityBlockingQueue:具有优先级的无界阻塞队列
  • threadFactory:用于创建新线程
  • handler:饱和策略,当阻塞队列满了,且没有空闲的工作线程,如果继续提交任务,必须采取一种策略处理该任务,线程池提供了4种策略:
  • AbortPolicy:直接抛出异常,默认策略
  • CallerRunsPolicy:用调用者所在的线程来执行任务
  • DiscardOldestPolicy:丢弃阻塞队列中靠最前的任务,并执行当前任务
  • DiscardPolicy:直接丢弃任务

当然也可以根据应用场景实现RejectedExecutionHandler接口,自定义饱和策略,如记录日志或持久化存储不能处理的任务。

线程池核心原理

线程池原理.png

execute方法注释

public void execute(Runnable command) {
        int c = ctl.get();
        if (workerCountOf(c) < corePoolSize) {//线程池里面的线程数量小于核心线程
            if (addWorker(command, true))
                //addWorker方法会开启一个新线程,如果线程池已停或者线程数量已满,返回false
                return;
            c = ctl.get();
        }
        //走到这里这里表示要么线程池停止了,要么核心线程满了
        if (isRunning(c) && workQueue.offer(command)) {
            //这里表示加入到阻塞队列里
            int recheck = ctl.get();
            if (! isRunning(recheck) && remove(command))
                reject(command);
            else if (workerCountOf(recheck) == 0)//如果线程池里面没有线程,有线程就不管,让原有线程处理阻塞队列的任务
                addWorker(null, false);//创建一个非核心线程
        }
        //这里表示线程池停了或阻塞队列满了,创建一个非核心线程处理新任务
        else if (!addWorker(command, false))
            //线程池停了,或者线程池的最大线程数量已经满了
            reject(command);
    }
目录
相关文章
|
5天前
|
并行计算 数据处理 调度
Python中的并发编程:探索多线程与多进程的奥秘####
本文深入探讨了Python中并发编程的两种主要方式——多线程与多进程,通过对比分析它们的工作原理、适用场景及性能差异,揭示了在不同应用需求下如何合理选择并发模型。文章首先简述了并发编程的基本概念,随后详细阐述了Python中多线程与多进程的实现机制,包括GIL(全局解释器锁)对多线程的影响以及多进程的独立内存空间特性。最后,通过实例演示了如何在Python项目中有效利用多线程和多进程提升程序性能。 ####
|
2月前
|
存储 缓存 Java
什么是线程池?从底层源码入手,深度解析线程池的工作原理
本文从底层源码入手,深度解析ThreadPoolExecutor底层源码,包括其核心字段、内部类和重要方法,另外对Executors工具类下的四种自带线程池源码进行解释。 阅读本文后,可以对线程池的工作原理、七大参数、生命周期、拒绝策略等内容拥有更深入的认识。
137 29
什么是线程池?从底层源码入手,深度解析线程池的工作原理
|
1月前
|
数据挖掘 程序员 调度
探索Python的并发编程:线程与进程的实战应用
【10月更文挑战第4天】 本文深入探讨了Python中实现并发编程的两种主要方式——线程和进程,通过对比分析它们的特点、适用场景以及在实际编程中的应用,为读者提供清晰的指导。同时,文章还介绍了一些高级并发模型如协程,并给出了性能优化的建议。
30 3
|
1月前
|
存储 运维 API
源码解密协程队列和线程队列的实现原理(一)
源码解密协程队列和线程队列的实现原理(一)
35 1
|
1月前
|
存储 安全 API
源码解密协程队列和线程队列的实现原理(二)
源码解密协程队列和线程队列的实现原理(二)
33 1
|
2月前
|
负载均衡 Java 调度
探索Python的并发编程:线程与进程的比较与应用
本文旨在深入探讨Python中的并发编程,重点比较线程与进程的异同、适用场景及实现方法。通过分析GIL对线程并发的影响,以及进程间通信的成本,我们将揭示何时选择线程或进程更为合理。同时,文章将提供实用的代码示例,帮助读者更好地理解并运用这些概念,以提升多任务处理的效率和性能。
60 3
|
1月前
|
Java 编译器 程序员
【多线程】synchronized原理
【多线程】synchronized原理
57 0
|
1月前
|
Java 应用服务中间件 API
nginx线程池原理
nginx线程池原理
31 0
|
2月前
|
存储 缓存 Java
JAVA并发编程系列(11)线程池底层原理架构剖析
本文详细解析了Java线程池的核心参数及其意义,包括核心线程数量(corePoolSize)、最大线程数量(maximumPoolSize)、线程空闲时间(keepAliveTime)、任务存储队列(workQueue)、线程工厂(threadFactory)及拒绝策略(handler)。此外,还介绍了四种常见的线程池:可缓存线程池(newCachedThreadPool)、定时调度线程池(newScheduledThreadPool)、单线程池(newSingleThreadExecutor)及固定长度线程池(newFixedThreadPool)。
|
2月前
|
并行计算 API 调度
探索Python中的并发编程:线程与进程的对比分析
【9月更文挑战第21天】本文深入探讨了Python中并发编程的核心概念,通过直观的代码示例和清晰的逻辑推理,引导读者理解线程与进程在解决并发问题时的不同应用场景。我们将从基础理论出发,逐步过渡到实际案例分析,旨在揭示Python并发模型的内在机制,并比较它们在执行效率、资源占用和适用场景方面的差异。文章不仅适合初学者构建并发编程的基础认识,同时也为有经验的开发者提供深度思考的视角。