by davy
由于工作中很少涉及多线程编程,我一直对java的多线程懵懵懂懂。最近突遇多线程的工作,故学习之。一时兴起,查看了java5自带的线程池的部分源码,深感震撼,恐忘却,故为此文以记之。网路上对java5的线程池讨论不少,但多数未能阐述其如何复用线程,本文拟弥补缺憾,重点叙述之。
java.util.concurrent. ThreadPoolExecutor即为线程池的实现,介绍一下这个类的几个重要的成员:
(1)private final BlockingQueue<Runnable> workQueue,线程池的缓冲队列,当前的线程不足以应付待处理的任务时,将任务放入缓冲队列。
(2)private volatile int corePoolSize,线程池保持的线程数
(3)private volatile int maximumPoolSize,线程池允许的最大线程数
(4)private volatile int poolSize,线程池当前线程数
线程池的使用者只需要调用ThreadPoolExecutor的execute(Runnable command),其代码如下:
publicvoid execute(Runnable command)
{
if (command == null) thrownew NullPointerException();
if (poolSize >= corePoolSize || !addIfUnderCorePoolSize(command))
{
if (runState == RUNNING && workQueue.offer(command))
{
if (runState != RUNNING || poolSize == 0)
ensureQueuedTaskHandled(command);
}
elseif (!addIfUnderMaximumPoolSize(command))
{
reject(command); // is shutdown or saturated
}
}
}
这些代码足够简洁,但暗藏玄机,我们简单阐述一下。
如果execute(null),则会抛出一个空指针异常。接下来重点关注if (poolSize >= corePoolSize || !addIfUnderCorePoolSize(command))语句,这句表达的是如果线程池的当前线程数超过了线程池保持的线程数,或者(小于保持的线程数时)新建线程失败的情况。简要分析一下.
(1)当程序刚启动时,poolSize=0,corePoolSize是我们初始化线程池时设置的,几乎一定>0,这时,程序肯定会执行addIfUnderCorePoolSize(command)(这个方法具体的实现后文讨论)方法为当前要处理的任务新建立一个线程并返回True,这会导致线程池里的线程数poolSize不断增加,并慢慢等于且超过可保持的线程数corePoolSize.这个过程就是新建线程,使线程数由0慢慢增长到可保持的线程数的过程。
(2)随着当前线程数poolSize增加,某时刻,poolSize会等于可保持的线程数corePoolSize,这时if (poolSize >= corePoolSize || !addIfUnderCorePoolSize(command))语句条件得到满足(注:addIfUnderCorePoolSize(command)不会被执行,会被跳过,逻辑),进入if逻辑。
(3)if (runState == RUNNING && workQueue.offer(command))被执行,如果是运行状态(此时的线程数等于可保持的线程数),就把待处理的任务放入缓冲队列,并判断放入队列是否成功。这个过程就是实际线程数等于可保持的线程数,暂时就不创建线程了,把新任务放入缓冲队列里。接着,检查一下放入队列操作是否成功了,如果放入队列成功了,还要检查一下线程池的状态,确保队列里的任务能被处理掉(这是通过ensureQueuedTaskHandled(command)来完成的)。如果把任务放入缓冲队列操作失败了(比如有界队列满了等),程序会执行elseif (!addIfUnderMaximumPoolSize(command)),请见(4)。
(4)程序执行elseif (!addIfUnderMaximumPoolSize(command)){},这个很好理解,这个过程是新建立线程,使线程数量由可保持的线程数量慢慢增加到线程池所允许的最大线程数量,然后,然后就没有然后了,线程数不能再增长了。那再有新任务怎么办呢?会被 reject(command);其实就是拒绝掉,如何拒绝,拒绝后怎么办是可以自己实现的。
到这里,相信大家对线程池的控制实现都应该比较了解了。可是线程究竟是如何被复用的呢?请继续关注简洁之美-java5线程池源码赏析(下)。
相关推荐
本文将深入探讨Java线程池的源码分析,并对比不同类型的线程池,以帮助开发者更好地理解和利用这一强大的工具。 首先,我们要理解Java线程池的核心类`java.util.concurrent.ThreadPoolExecutor`,它是所有自定义...
JDBC是Java平台上的标准API,用于访问各种类型的数据库。它提供了一组接口和类,使得Java开发者可以编写数据库无关性的代码,从而轻松地与不同数据库系统交互。MySQL Connector/J实现了这些JDBC接口,使得Java应用...
阿里云的taobao-sdk-java-auto.jar及源码, 感兴趣的朋友可以下载一下。。。。。。。
Java语言开发的简洁实用的日期选择控件,源码文件功能说明: [DateChooser.java] Java 日期选择控件(主体类) [public] [TablePanel.java] 日历表格面板 [ConfigLine.java] 控制条类 [RoundBox.java] ...
线程池是Java多线程编程中的重要概念,它的出现是为了高效、有序地管理线程资源,避免频繁创建和销毁线程导致的性能开销。本文将深入解析线程池的管理源码,帮助读者理解其工作原理和优化策略。 在Java中,`java....
java线程池源码 cThreadPool 项目描述:对java.util.concurrent包下线程池相关源码进行重新实现,深入研究和学习线程池超时机制、饱和策略、生命周期等知识 ThreadPoolExecutor类下部分方法和内部类介绍: 1、Worker...
描述 "Java 线程池完整源码" 说明了这篇文章的内容是关于 Java 线程池的完整实现代码,包括线程池的源代码、配置文件的解析和线程池的管理等方面。 标签解析 标签 "Java 线程池完整源码" 说明了这篇文章的主题是...
超市系统源码--小型JAVA开发-超市系统后台源码 超市系统源码--小型JAVA开发-超市系统后台源码 超市系统源码--小型JAVA开发-超市系统后台源码 超市管理系统源码--JAVA开发-超市系统后台源码
流行框架:SpringMvc+Spring+mybatis+maven 数据库:mysql web框架:bootstrap,My97DatePickers 定时器任务:job 事务管理:mysql事务处理
本项目源码是个人基于Java实现的线程池,旨在理解和掌握线程池的工作原理。 线程池的核心概念包括以下几个部分: 1. **工作队列(Work Queue)**:线程池内部维护了一个任务队列,用来存储待执行的任务。当提交新...
在Java并发编程中,线程池(ThreadPoolExecutor)是一个至关重要的工具,它允许开发者有效地管理线程资源,提高系统的性能和响应性。JDK 1.5引入了java.util.concurrent包,其中包含了线程池的实现,使得并发编程...
要理解`java线程池threadpool简单使用源码`,你需要查看`src`目录下的Java文件,了解如何实例化`ThreadPoolExecutor`,设置相关参数,以及如何提交任务到线程池。同时,查看源码中对`ThreadGroup`的使用,理解它如何...
基于C++11 实现的动态线程池源码示例.zip 【资源说明】 使用 C++11 实现的动态线程池,主要特性: 使用简单,不易出错。 支持线程复用,提升性能。 支持懒惰创建线程。 必要时自动回收空闲的线程。 【快速上手】 #...
在"**C++线程池源码**"中,我们可以探索如何在C++环境中实现这样的机制。 线程池的工作原理通常包括以下几个关键部分: 1. **工作队列(Work Queue)**:这是描述中提到的关键组件,它负责存储待处理的任务。当有...
5. **错误处理和同步**:线程池操作可能会遇到错误,如资源不足等,因此需要适当的错误处理机制。同时,为了确保线程安全,可能需要使用互斥量、事件或临界区等同步原语。 6. **性能优化**:线程池的性能优化可能...
这个压缩包 "selenium-java-2.47.1.zip" 包含了Selenium的Java版本,具体是2.47.1的更新,发布于2015年8月。这个版本在当时是一个稳定且广泛使用的版本,它提供了丰富的API,支持多种浏览器,并且可以与各种测试框架...
Java实用简洁的问答_社区系统源码 Java实用简洁的问答_社区系统源码 Java实用简洁的问答_社区系统源码 Java实用简洁的问答_社区系统源码 Java实用简洁的问答_社区系统源码 Java实用简洁的问答_社区系统源码 ...
在本压缩包“易语言源码易语言Mysql线程池2.0模块源码.rar”中,包含的是一个易语言编写的MySQL线程池模块的源代码,版本为2.0。线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动...
9. **线程池的性能优化**:线程池的性能不仅取决于线程的数量,还与任务的性质、系统资源以及线程的上下文切换频率等因素有关。因此,合理的线程池大小设置、任务粒度控制等都是优化的重点。 总的来说,“linux ...
标题中的“Java实现的线程池、消息队列功能”是指在Java编程中,如何利用编程技术实现线程池和消息队列这两种重要的并发处理机制。线程池和消息队列是解决多线程环境下资源管理和任务调度的有效手段,它们在高并发、...