`

简洁之美-java5线程池源码赏析(上)

阅读更多
              简洁之美-java5线程池源码赏析(上)

                    by davy

         由于工作中很少涉及多线程编程,我一直对java的多线程懵懵懂懂。最近突遇多线程的工作,故学习之。一时兴起,查看了java5自带的线程池的部分源码,深感震撼,恐忘却,故为此文以记之。网路上对java5的线程池讨论不少,但多数未能阐述其如何复用线程,本文拟弥补缺憾,重点叙述之。

         java.util.concurrent. ThreadPoolExecutor即为线程池的实现,介绍一下这个类的几个重要的成员:

1private final BlockingQueue<Runnable> workQueue,线程池的缓冲队列,当前的线程不足以应付待处理的任务时,将任务放入缓冲队列。

2private volatile int   corePoolSize,线程池保持的线程数

3private volatile int   maximumPoolSize,线程池允许的最大线程数

4private volatile int   poolSize,线程池当前线程数

         线程池的使用者只需要调用ThreadPoolExecutorexecute(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线程池源码赏析(下)。

分享到:
评论

相关推荐

    taobao-sdk-java-auto源码

    阿里云的taobao-sdk-java-auto.jar及源码, 感兴趣的朋友可以下载一下。。。。。。。

    mysql-connector-java-5.1.37jar包和源码

    JDBC是Java平台上的标准API,用于访问各种类型的数据库。它提供了一组接口和类,使得Java开发者可以编写数据库无关性的代码,从而轻松地与不同数据库系统交互。MySQL Connector/J实现了这些JDBC接口,使得Java应用...

    java源码包---java 源码 大量 实例

     Java语言开发的简洁实用的日期选择控件,源码文件功能说明:  [DateChooser.java] Java 日期选择控件(主体类) [public]  [TablePanel.java] 日历表格面板  [ConfigLine.java] 控制条类  [RoundBox.java] ...

    javathread类源码-thread-pool-source-code:JAVA线程池源码解读

    java thread类源码 thread-pool-source-code JAVA线程池源码解读

    线程池管理源码 java 源码

    线程池是Java多线程编程中的重要概念,它的出现是为了高效、有序地管理线程资源,避免频繁创建和销毁线程导致的性能开销。本文将深入解析线程池的管理源码,帮助读者理解其工作原理和优化策略。 在Java中,`java....

    java线程池源码-cThreadPool:JAVA线程池源码分析与重写

    java线程池源码 cThreadPool 项目描述:对java.util.concurrent包下线程池相关源码进行重新实现,深入研究和学习线程池超时机制、饱和策略、生命周期等知识 ThreadPoolExecutor类下部分方法和内部类介绍: 1、Worker...

    java线程池完整代码

    描述 "Java 线程池完整源码" 说明了这篇文章的内容是关于 Java 线程池的完整实现代码,包括线程池的源代码、配置文件的解析和线程池的管理等方面。 标签解析 标签 "Java 线程池完整源码" 说明了这篇文章的主题是...

    易语言完美的线程池源码

    不过,标题中提到的是“易语言完美的线程池源码”,这可能是指使用易语言实现的线程池代码,但标签却是"C++",这可能意味着提供的资源中包含了易语言和C++两种语言关于线程池的示例。 6. **项目文件解析** - `简单...

    Android-AppExecutor应用线程池可以指定任务的优先级完全kotlin

    通过阅读和理解这个源码,我们可以学习到如何利用Kotlin来创建这样一个具有优先级控制的线程池,同时也能看到如何将这个线程池集成到Android应用中,以优化任务执行的效率和顺序。 总之,理解和掌握如何在Android...

    selenium-java jar文件及源码

    本文将深入探讨Selenium Java JAR文件及其源码,以及它们在"selelnium2"标签中的重要性。 首先,`selenium-2.37.0`是Selenium的一个特定版本号,它包含了Selenium WebDriver的主要组件。WebDriver是一个用于控制...

    P2P借贷项目--java源码+MySQL

    流行框架:SpringMvc+Spring+mybatis+maven 数据库:mysql web框架:bootstrap,My97DatePickers 定时器任务:job 事务管理:mysql事务处理

    线程池源码

    本项目源码是个人基于Java实现的线程池,旨在理解和掌握线程池的工作原理。 线程池的核心概念包括以下几个部分: 1. **工作队列(Work Queue)**:线程池内部维护了一个任务队列,用来存储待执行的任务。当提交新...

    线程池源码解析-多线程

    本文将深入解析线程池的源码,特别关注其中的`AtomicInteger`类以及线程池状态的表示。 `AtomicInteger`是Java并发包`java.util.concurrent.atomic`中的一个原子类型类,它提供了在多线程环境下安全地修改整型变量...

    基于C++11 实现的动态线程池源码示例.zip

    基于C++11 实现的动态线程池源码示例.zip 【资源说明】 使用 C++11 实现的动态线程池,主要特性: 使用简单,不易出错。 支持线程复用,提升性能。 支持懒惰创建线程。 必要时自动回收空闲的线程。 【快速上手】 #...

    java线程池源码-java-source:Java源码学习多线程、线程池、集合

    本文将深入探讨Java线程池的源码,了解其工作原理和关键组件。 首先,我们来看`ExecutorService`接口,它是线程池的核心接口,提供了执行任务的基本方法,如`execute()`用于提交Runnable任务,`submit()`用于提交...

    网站压力测试程序----附带java源码

    本资源提供的是一款用Java编写的网站压力测试程序,通过分析其源码,我们可以深入理解如何构建这样的工具。 1. **并发测试原理**: 并发测试是指在模拟多个用户同时访问同一网站或应用的过程,以检验服务器、...

    基于java的开发源码-泡泡堂战车游戏JAVA版源码.zip

    基于java的开发源码-泡泡堂战车游戏JAVA版源码.zip 基于java的开发源码-泡泡堂战车游戏JAVA版源码.zip 基于java的开发源码-泡泡堂战车游戏JAVA版源码.zip 基于java的开发源码-泡泡堂战车游戏JAVA版源码.zip 基于java...

    selenium-java-2.47.1.zip

    这个压缩包 "selenium-java-2.47.1.zip" 包含了Selenium的Java版本,具体是2.47.1的更新,发布于2015年8月。这个版本在当时是一个稳定且广泛使用的版本,它提供了丰富的API,支持多种浏览器,并且可以与各种测试框架...

    Java实用简洁的问答_社区系统源码.zip

    Java实用简洁的问答_社区系统源码 Java实用简洁的问答_社区系统源码 Java实用简洁的问答_社区系统源码 Java实用简洁的问答_社区系统源码 Java实用简洁的问答_社区系统源码 Java实用简洁的问答_社区系统源码 ...

    线程池源码分析

    线程池ThreadPoolExecutor的源码分析,含中文注释,深入了解线程池的构造

Global site tag (gtag.js) - Google Analytics