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线程池源码赏析(下)。
相关推荐
课程作业-基于C语言实现线程池源码.zip课程作业-基于C语言实现线程池源码.zip课程作业-基于C语言实现线程池源码.zip课程作业-基于C语言实现线程池源码.zip课程作业-基于C语言实现线程池源码.zip课程作业-基于C语言...
JAVA实现的线程池,可以直接在正规大型项目中套用。如果有不懂的,可以问我,QQ:452242541,加时注明csdn
java线程池的源码分析以及各种池之间的对比;
阿里云的taobao-sdk-java-auto.jar及源码, 感兴趣的朋友可以下载一下。。。。。。。
mysql-connector-java-5.1.37jar包和源码下载 最新mysqljar包
Java语言开发的简洁实用的日期选择控件,源码文件功能说明: [DateChooser.java] Java 日期选择控件(主体类) [public] [TablePanel.java] 日历表格面板 [ConfigLine.java] 控制条类 [RoundBox.java] ...
1.媲美java线程池框架,整套源码资源,使用Intellij Idea开发工具,JDK1.8以上 2.带有测试代码 3.可以根据项目实际情况任意调整代码 4.任务队列、拒绝策略 5.BasicThreadPool.java、LinkedRunnableQueue.java、...
java thread类源码 thread-pool-source-code JAVA线程池源码解读
java线程池源码 cThreadPool 项目描述:对java.util.concurrent包下线程池相关源码进行重新实现,深入研究和学习线程池超时机制、饱和策略、生命周期等知识 ThreadPoolExecutor类下部分方法和内部类介绍: 1、Worker...
线程池管理源码 线程池管理源码 线程池管理源码
java 线程池 完整 源码 java 线程池 完整 源码
超市系统源码--小型JAVA开发-超市系统后台源码 超市系统源码--小型JAVA开发-超市系统后台源码 超市系统源码--小型JAVA开发-超市系统后台源码 超市管理系统源码--JAVA开发-超市系统后台源码
TOMCAT的线程池源码封装,有想学习TOMCAT的线程池源,或者觉得JDK的线程池源码效率不高,可以下载此代码
selenium-java jar文件及源码
线程池源码工程文件 自己用java写的线程池
易语言源码易语言IOCP线程池源码.rar
Reference: 《创建Java线程池》[1],《Java线程:新特征-线程池》[2], 《Java线程池学习》[3],《线程池ThreadPoolExecutor使用简介》[4],《Java5中的线程池实例讲解》[5],《ThreadPoolExecutor使用和思考》[6] ...
JDK1.5线程池源码及详细注释 深入研究java线程原理
java线程池源码 Java源码学习
非常详细的线程池函数接口分析,可以帮助初学者加深对线程池的理解,更好的去把线程池运用到实例中去,线程池就是多个线程组合在一起的集合,就像一家公司一样,由多个员工组成的一个集合,当有任务时, 这些线程就...