ThreadPoolExecutor添加线程是通过 execute(Runnable command),此方法代码行数不多,但是由于太精炼了,不大好读懂,理解完之后,特写下笔记加深印象.
一句话解释:
如果BlockingQueue没有大小限制,如果在执行的线程个数小于corePoolSize,则自动执行,否则当前线程存入BlockingQueue.
备注:如果BlockingQueue有限制,超出的线程要么拒绝,要么抢跑直接执行(需要当前线程个数没有超过maximumPoolSize).
下面是具体的代码,已经添加注释,如果有问题欢迎大家指出.
//ThreadPoolExecutor public void execute(Runnable command) { if (command == null) throw new NullPointerException(); //--如果核心线程已经用尽( poolSize >= corePoolSize ), 进入if分支 //--核心线程没用完,立即执行线程,不进入if分支(!addIfUnderCorePoolSize(command)) if (poolSize >= corePoolSize /*核心线程没空余*/ || !addIfUnderCorePoolSize(command)/*核心线程有空余*/) { //--如果核心线程已经用尽, 并且runState == RUNNING, 则添加command到workQueue中去 if (runState == RUNNING && workQueue.offer(command)) { if (runState != RUNNING || poolSize == 0) //如果线程池状态不为RUNNING,或者正在工作的线程个数为0,则尽量保证添加的Command被处理(Reject) ensureQueuedTaskHandled(command); } //--如果workQueue已满,则尝试直接执行线程(需要保证当前运行线程<maximumPoolSize,感觉好像插队了一样,不公平) else if (!addIfUnderMaximumPoolSize(command)) //如果poolSize>=maximumPoolSize,则拒绝(通过抛出运行时异常) reject(command); // is shutdown or saturated } }
几点注意
- workers中存放的是 正在执行的线程,当执行完毕,并且BlockingQueue中无数据时,线程会会自动从workers中删除 (通过Worker.workerDone(this))
- workQueue中存放的是 由于corePoolSize限制,来不及执行的线程.如果由于workQueue的限制导致存放不下的,有可能抢跑而直接执行(前提是线程数量小于maximumPoolSize,否则直接拒绝).
- ThreadPoolExecutor 构造函数中有2个限制:一个是核心线程数量,一个是最大线程数量. 上面函数不好理解是因为有一个可能潜在的限制,就是缓存队列(BlockingQueue)的大小限制.
- 放入BlockingQueue中的线程何时执行: 每一个Worker初始化之后,会立即去执行,但是当执行完成之后即会尝试从BlockingQueue中取线程执行.下面是对应代码.
//Worker public void run() { try { Runnable task = firstTask; firstTask = null; //task = getTask()就是尝试从队列中取线程来执行 while (task != null || (task = getTask()) != null) { runTask(task); task = null; } } finally { workerDone(this); } }
相关推荐
《ThreadPoolExecutor源码解析》 ThreadPoolExecutor是Java并发编程中重要的组件,它是ExecutorService接口的实现,用于管理和调度线程的执行。理解其源码有助于我们更好地控制并发环境下的任务执行,提高系统的...
ThreadPoolExecutor源码解析.md
【大漠多线程范例源码】是一个关于多线程编程的实例集合,由知名IT专家"大漠"提供,旨在帮助开发者深入理解和实践Java或其他编程语言中的多线程技术。多线程是现代软件开发中不可或缺的一部分,特别是在并发处理、高...
线程池原理-ThreadPoolExecutor源码解析 1.构造方法及参数 2.阻塞对列: BlockingQueue 3.线程工厂: DefaultThreadFactory 4.拒绝策略: RejectedExecutionHandler 5.执行线程 Executor
1. **线程的概念**:线程是操作系统分配CPU时间的基本单位,一个进程可以有多个线程,它们共享进程的内存空间,各自拥有独立的执行流,使得程序能够并行处理多个任务。 2. **Java中的线程创建方式**: - 继承`...
这里提到的“多线程换IP源码(调用鱼刺线程池)”是一个程序,它利用多线程技术来实现IP地址的快速切换,并且这个过程调用了名为“鱼刺线程池”的组件。下面将详细解释这两个主要知识点。 **多线程** 多线程是一种...
线程池ThreadPoolExecutor底层原理源码分析
《JDK之ThreadPoolExecutor源码分析1》 在Java编程中,线程池是一种高效的管理线程的方式,它通过复用已存在的线程来避免频繁创建和销毁线程带来的开销。ThreadPoolExecutor作为Java中的线程池实现,其内部机制相当...
### 三、线程池添加线程源码解析 线程池添加线程的过程主要涉及以下几个步骤: 1. 检查线程池是否处于允许添加新线程的状态。 2. 如果线程池的worker线程数量小于核心线程数,创建新的worker线程。 3. 如果队列未...
本资源包含的"JAVA线程编程源码"很可能提供了一些示例和详细解释,帮助开发者深入理解线程的工作原理。 1. **线程的创建** - 实现`Runnable`接口:创建一个实现了Runnable接口的类,然后将其实例传递给Thread类的...
在Java中,线程的创建主要有两种方式:一是通过继承`java.lang.Thread`类,二是实现`java.lang.Runnable`接口。继承Thread类的方法简单直接,但限制了类的继承性;而实现Runnable接口则更为灵活,可以避免单继承的...
本资源"多线程爬虫源码.zip"提供了一个使用多线程技术实现的网络爬虫的源代码,旨在帮助开发者理解和实践如何构建高效的爬虫系统。 首先,我们需要理解什么是多线程。在计算机科学中,线程是程序执行的基本单元,一...
本资源提供了详细的Java多线程设计模式的解析,包括源码分析,帮助开发者深入理解并熟练应用这些模式。 在多线程环境中,设计模式是解决常见问题的最佳实践,它们可以帮助开发者创建高效、可维护的并发代码。以下是...
Java多线程并发实战与源码分析是Java开发中至关重要的一部分,它涉及到程序性能优化、系统资源高效利用以及复杂逻辑的正确同步。本书主要聚焦于Java多线程的基础理论和实际应用,虽然书中实例和源码相对较少,但仍然...
为了有效管理线程,Java提供了`ExecutorService`和`ThreadPoolExecutor`,它们可以重用预创建的线程,避免频繁创建和销毁线程的开销。线程池可以设置核心线程数、最大线程数、线程存活时间和任务队列等参数。 6. *...
"火山安卓多线程技术源码"提供了一套关于如何在Android平台上运用多线程的实例代码。 1. **线程基础** - **线程概念**:线程是程序执行的最小单元,每个进程可以有多个线程同时执行。 - **主线程**:Android中的...
本篇文章将深入探讨一个基于多线程的Web服务器Java源码,帮助你理解如何在Java中实现一个基本的Web服务器,特别关注其多线程机制。 【描述】多线程技术在Web服务器中的应用 多线程是Java编程中的核心特性,它允许...
在Java中,实现多线程主要有两种方式:继承Thread类和实现Runnable接口。接下来,我们将深入探讨这两个方法以及相关的知识点。 1. 继承Thread类 当一个类继承了Thread类,它就自动成为一个线程类。你需要重写...
Java 5引入了ExecutorService和ThreadPoolExecutor,它们允许创建线程池,可以有效管理线程生命周期,减少线程创建和销毁的开销。通过Executors工厂方法可以方便地创建各种类型的线程池。 5. 守护线程 守护线程...
### 线程池 `ThreadPoolExecutor` 原理源码分析 #### 一、概述 线程池作为 Java 并发编程中的重要组件,在实际应用中被广泛使用。其核心类 `ThreadPoolExecutor` 实现了对线程的管理、调度等功能。本文将围绕 `...