简洁之美-java5线程池源码赏析(下)
by davy
在上篇中,大家了解线程池对线程的控制,本篇将重点介绍线程是如何被复用的。其实关键就在于,addIfUnderCorePoolSize(command)和addIfUnderMaximumPoolSize(command)新建立的线程会不停地从缓冲队列里获取待执行的任务并执行。只要线程池的缓冲队里有任务,线程就不会消亡,就会得到复用。缓冲队列里没有待处理的任务,并且线程超过了预定义的允许空闲时间,线程就会消亡。接下来看一下addIfUnderCorePoolSize(Runnable command)方法,其代码如下:
privateboolean addIfUnderCorePoolSize(Runnable firstTask)
{
Thread t = null;
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try
{
if (poolSize < corePoolSize && runState == RUNNING)
t = addThread(firstTask);
} finally
{
mainLock.unlock();
}
if (t == null) returnfalse;
t.start();
returntrue;
}
简单地说,就是先建立线程,并启动线程。我们关心的是线程启动后,其执行的任务时什么。addThread(firstTask)的代码如下:
private Thread addThread(Runnable firstTask)
{
Worker w = new Worker(firstTask);
Thread t = threadFactory.newThread(w);
if (t != null) {
w.thread = t;
workers.add(w);
int nt = ++poolSize;
if (nt > largestPoolSize)
largestPoolSize = nt;
}
return t;
}
Worker是一个内部类,是对真正要执行的任务的包装。Thread t = threadFactory.newThread(w);其实就是新建立了一个Thread实例t,并使该线程t的target=W(即Worker).这样当线程t启动后,Worker.run()会执行。下面就来看一下Worker的真面目吧,代码如下(限于篇幅只贴关键代码):
publicvoid run()
{
Try
{
Runnable task = firstTask;
firstTask = null;
while (task != null || (task = getTask()) != null)
{
runTask(task);
task = null;
}
} finally
{
workerDone(this);
}
}
重点就是while循环,当前处理的任务不为null就执行当前的任务;如果当前处理的任务是null就从线程池的缓冲队列里获取任务来执行。getTask()其实就是从缓冲队列取出任务,不再详细介绍。也就是说,只要缓冲队列里还有待处理的任务,Worker的run()方法就会执行下去,而执行Worker的Thread实例t就不会空闲,不会消亡。这样线程就得到了复用。
篇后语:
高手就是高手,顶级高手的代码没有过多的华丽,其朴素、精炼、简洁令人叹为观止。JDK中随处可见顶级高手的代码,不妨观摩拜读。在jdk1.5线程池的代码中,没有Synchronized关键字,用的都是Lock和同步(阻塞)队列,因为后者的性能更优。在下才疏学浅,生怕粗俗肤浅的理解会亵渎高手的代码。因此,文中不当之处,恳请大家批评指正,不胜感激。
相关推荐
Java线程池是Java并发编程中的重要组成部分,它在多线程和高并发场景下扮演着关键角色。本文将深入探讨Java线程池的源码分析,并对比不同类型的线程池,以帮助开发者更好地理解和利用这一强大的工具。 首先,我们要...
阿里云的taobao-sdk-java-auto.jar及源码, 感兴趣的朋友可以下载一下。。。。。。。
MySQL Connector/J是MySQL数据库的Java连接器,它允许Java应用程序通过JDBC(Java Database Connectivity)接口与MySQL数据库进行通信。在本案例中,"mysql-connector-java-5.1.37.jar" 是一个特定版本的MySQL JDBC...
基于java的开发源码-Java项目源码在线相册系统.zip 基于java的开发源码-Java项目源码在线相册系统.zip 基于java的开发源码-Java项目源码在线相册系统.zip 基于java的开发源码-Java项目源码在线相册系统.zip 基于java...
Java语言开发的简洁实用的日期选择控件,源码文件功能说明: [DateChooser.java] Java 日期选择控件(主体类) [public] [TablePanel.java] 日历表格面板 [ConfigLine.java] 控制条类 [RoundBox.java] ...
项目描述:对java.util.concurrent包下线程池相关源码进行重新实现,深入研究和学习线程池超时机制、饱和策略、生命周期等知识 ThreadPoolExecutor类下部分方法和内部类介绍: 1、Worker类: 描述:Worker类实现...
描述 "Java 线程池完整源码" 说明了这篇文章的内容是关于 Java 线程池的完整实现代码,包括线程池的源代码、配置文件的解析和线程池的管理等方面。 标签解析 标签 "Java 线程池完整源码" 说明了这篇文章的主题是...
超市系统源码--小型JAVA开发-超市系统后台源码 超市系统源码--小型JAVA开发-超市系统后台源码 超市系统源码--小型JAVA开发-超市系统后台源码 超市管理系统源码--JAVA开发-超市系统后台源码
本项目源码是个人基于Java实现的线程池,旨在理解和掌握线程池的工作原理。 线程池的核心概念包括以下几个部分: 1. **工作队列(Work Queue)**:线程池内部维护了一个任务队列,用来存储待执行的任务。当提交新...
流行框架:SpringMvc+Spring+mybatis+maven 数据库:mysql web框架:bootstrap,My97DatePickers 定时器任务:job 事务管理:mysql事务处理
在Java并发编程中,线程池(ThreadPoolExecutor)是一个至关重要的工具,它允许开发者有效地管理线程资源,提高系统的性能和响应性。JDK 1.5引入了java.util.concurrent包,其中包含了线程池的实现,使得并发编程...
要理解`java线程池threadpool简单使用源码`,你需要查看`src`目录下的Java文件,了解如何实例化`ThreadPoolExecutor`,设置相关参数,以及如何提交任务到线程池。同时,查看源码中对`ThreadGroup`的使用,理解它如何...
在"**C++线程池源码**"中,我们可以探索如何在C++环境中实现这样的机制。 线程池的工作原理通常包括以下几个关键部分: 1. **工作队列(Work Queue)**:这是描述中提到的关键组件,它负责存储待处理的任务。当有...
5. **错误处理和同步**:线程池操作可能会遇到错误,如资源不足等,因此需要适当的错误处理机制。同时,为了确保线程安全,可能需要使用互斥量、事件或临界区等同步原语。 6. **性能优化**:线程池的性能优化可能...
在本压缩包“易语言源码易语言Mysql线程池2.0模块源码.rar”中,包含的是一个易语言编写的MySQL线程池模块的源代码,版本为2.0。线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动...
5. **任务提交与执行**:当有新的任务需要执行时,开发者可以调用线程池的接口将其添加到任务队列,线程池会自动选择空闲线程来执行任务。 6. **线程调度策略**:线程池可能包含不同类型的调度策略,如优先级调度、...
标题中的“Java实现的线程池、消息队列功能”是指在Java编程中,如何利用编程技术实现线程池和消息队列这两种重要的并发处理机制。线程池和消息队列是解决多线程环境下资源管理和任务调度的有效手段,它们在高并发、...
5. **使用线程池** - 初始化线程池:调用初始化函数,设置线程池的大小、任务队列等。 - 添加任务:将任务数据结构插入任务队列,并通知线程池有新任务可用。 - 消耗任务:线程从任务队列中取出任务并执行,直至...
同时,理解并掌握线程池的原理和实现,对于其他编程语言(如Java、C#等)的线程池使用也会有启发作用,因为线程池的设计思想是跨语言的。 在实际项目中,线程池广泛应用于服务器端编程、高并发场景以及需要长时间...
java线程池源码解读Java 新手到精通(行业兼容)课程大纲 标题 分解 时间 1 介绍 为什么选择 Java Java 设计目标和历史 Java 编程语言在行业中的作用 Java语言的特点 JVM——Java的核心 字节码——神奇的代码 不同...