框架最核心的类是ThreadPoolExecutor,它是Java线程池的实现类,通过Executors工具类,可以创建3种类型的ThreadPoolExecutor:

首先附上ThreadPoolExecutor的构造函数

ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)

FixedThreadPool

可重用固定线程数的线程池。实现源码:

public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}

在这里,corePoolSizemaximumPoolSize都设置成了创建时指定的线程数nThread,当线程池中的线程数大于corePoolSize时,keepAliveTime为多余的空闲线程等待新任务的时间,超过这个时间后线程将会被终止。在这里设置为0L,意味着多余的空闲线程将会被立即终止。

FixedPoolThreadexecute()方法运行流程如下:

  • 如果当前运行的线程少于corePoolSize,则创建新的线程来执行任务。
  • 在线程池完成预热之后(当前运行的线程数等于corePoolSize),将任务加入LinkedBlockingQueue
  • 线程执行完1中的任务后,会在循环中反复从LinkedBlockingQueue获取任务来执行

由于它采用了LinkedBlockingQueue来作为线程池的工作队列,这是一个无界队列(队列容量为Integer.MAX_VALUE)。所以将会为线程池带来如下影响:

  1. 当线程池的线程数达到corePoolSize之后,新的任务将会在无界队列中等待,因此线程池中的线程不会超过corePoolSize

  2. 由于1,使用无界队列时maximumPoolSize将是一个无效参数;

  3. 由于1和2,使用无界队列时keepAliveTime将是一个无效参数

  4. 由于使用无界队列,运行中的FixedThreadPool(未执行shutdown()或shutdownNow())不会拒绝任务。

SingleThreadExecutor

使用单个worker线程的Executor,下面是源码实现:

public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}

SingleThreadExecutorcorePoolSizemaximumPoolSize都被设置成1,其他参数则与FixedThreadPool相同,它使用无界队列的影响与FixedThreadPool是同样的。下面是它的运行流程图:

  • 如果当前没有线程在运行,则创建一个新的线程
  • 当线程池中有且仅有一个运行的线程,将任务加入LinkedBlockingQueue
  • 线程执行完1中的任务后,会在循环中反复从LinkedBlockingQueue获取任务执行。

CachedThreadPool

一个会根据需要创建新线程的线程池,下面是源码实现:

public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}

它的corePoolSize被设置为0,maximumPoolSize设置为Integer.MAX_VALUE,即maximumPool是无界的;把keepAliveTime设置成60L,意味着该线程池中空闲线程等待新任务的最长时间为60秒,超时则被会终止。CachedThreadPool使用没有容量的SynchronousQueue作为线程池的工作队列,但CachedThreadPoolmaximumPool是无界的,意味着,如果主线程提交任务的速度高于maximumPool中线程处理的速度,它将会不断的创建新的线程,直到耗尽所有CPU和内存资源。它的运行流程如图:

  • 首先执行SynchronousQueue.offer(task),如果当前maximumPool中有空闲线程正在执行SynchronousQueue.poll(keepAliveTime,TimeUnit.NANOSECONDS),那么主线程执行的offer操作与空闲线程执行的poll操作配对成功,主线程把任务交给空闲线程执行,execute执行成功,否则执行下面的操作。
  • maximumPool为空,或者其中没有空闲线程时,将没有线程执行poll操作,那么CachedThreadPool会创建一个新的线程,execute方法执行成功。
  • 在上面的步骤中,线程将任务执行完后,变为空闲状态,将会执行poll操作,空闲线程继续等待新的任务到来并配对执行,如果超过60s,则线程将会被终止。由于超过60秒的空闲线程将会被终止,所以长时间保持空闲的CachedThreadPool不会使用任何资源

CachedThreadPool的任务传递示意图:

ScheduledThreadPoolExecutor

主要用来在给定的延迟之后运行任务,或者定期执行任务,下面是源码实现:

public ScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
new DelayedWorkQueue());
}

该类直接继承自ThreadPoolExecutor,为的是能直接使用已经实现的方法,而且,它新加了几个方法:

  • public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit)

    //向定时任务线程池提交一个延时Runnable任务(仅执行一次)

  • public ScheduledFuture schedule(Callable callable, long delay, TimeUnit unit);

    //向定时任务线程池提交一个延时的Callable任务(仅执行一次)

  • public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay,long period, TimeUnit unit)

    //向定时任务线程池提交一个固定时间间隔执行的任务

  • public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay,long delay, TimeUnit unit);

    //向定时任务线程池提交一个固定延时间隔执行的任务

也可以向其直接提交普通任务,相当于延时和周期都为0的任务。这里构造时的数值含义与前面的类似,就不赘述了。下面是基本运行流程图:

  • 主线程提交普通任务或有延时或周期的任务。并将任务加入具有优先性质的阻塞队列
  • 线程池中的线程每次通过take()方法获取任务,然后从任务的getDelay()方法获取应当延时的时间,当延时达到,执行任务。执行完毕后,判断这是不是一个周期任务,如果是,则继续延时执行任务,如果不是,则继续调用take方法获取任务,如果没有获取到任务,空闲线程将会被终止。

FutureTask

代表异步计算的结果,根据FutureTask.run()方法执行状况,可以分为下面三种状态:

  • 未启动:FutureTask.run()方法还没有被执行前
  • 已启动:FutureTask.run()方法正在执行
  • 已完成:FutureTask.run()方法正常结束、被取消、执行抛出异常、异常结束

下面是FutureTask对应get(),cancel()方法执行示意图:

Executor 框架详解的更多相关文章

  1. 跟着阿里p7一起学java高并发 - 第19天:JUC中的Executor框架详解1,全面掌握java并发核心技术

    这是java高并发系列第19篇文章. 本文主要内容 介绍Executor框架相关内容 介绍Executor 介绍ExecutorService 介绍线程池ThreadPoolExecutor及案例 介 ...

  2. java高并发系列 - 第20天:JUC中的Executor框架详解2之ExecutorCompletionService

    这是java高并发系列第20篇文章. 本文内容 ExecutorCompletionService出现的背景 介绍CompletionService接口及常用的方法 介绍ExecutorComplet ...

  3. mina框架详解

     转:http://blog.csdn.net/w13770269691/article/details/8614584 mina框架详解 分类: web2013-02-26 17:13 12651人 ...

  4. Spark2.1.0——内置Web框架详解

    Spark2.1.0——内置Web框架详解 任何系统都需要提供监控功能,否则在运行期间发生一些异常时,我们将会束手无策.也许有人说,可以增加日志来解决这个问题.日志只能解决你的程序逻辑在运行期的监控, ...

  5. jQuery Validate验证框架详解

    转自:http://www.cnblogs.com/linjiqin/p/3431835.html jQuery校验官网地址:http://bassistance.de/jquery-plugins/ ...

  6. lombok+slf4j+logback SLF4J和Logback日志框架详解

    maven 包依赖 <dependency> <groupId>org.projectlombok</groupId> <artifactId>lomb ...

  7. [Cocoa]深入浅出 Cocoa 之 Core Data(1)- 框架详解

    Core data 是 Cocoa 中处理数据,绑定数据的关键特性,其重要性不言而喻,但也比较复杂.Core Data 相关的类比较多,初学者往往不太容易弄懂.计划用三个教程来讲解这一部分: 框架详解 ...

  8. iOS 开发之照片框架详解(2)

    一. 概况 本文接着 iOS 开发之照片框架详解,侧重介绍在前文中简单介绍过的 PhotoKit 及其与 ALAssetLibrary 的差异,以及如何基于 PhotoKit 与 AlAssetLib ...

  9. Quartz.NET作业调度框架详解

    Quartz.NET作业调度框架详解 http://www.cnblogs.com/lmule/archive/2010/08/28/1811042.html

随机推荐

  1. 《剑指offer》第八题(重要!查找二叉树的中序遍历的下一个结点)

    文件一:main.cpp // 面试题:二叉树的下一个结点 // 题目:给定一棵二叉树和其中的一个结点,如何找出中序遍历顺序的下一个结点? // 树中的结点除了有两个分别指向左右子结点的指针以外,还有 ...

  2. Codeforces 535C - Tavas and Karafs

    535C - Tavas and Karafs 思路:对于满足条件的r,max(hl ,hl+1 ,hl+2 ,......,hr )<=t(也就是hr<=t)且∑hi<=t*m.所 ...

  3. asp.net Core MVC + form validation + ajax form 笔记

    asp.net Core MVC 有特别处理form,controller可以自己处理model的验证,最大的优势是写form时可以少写代码 先了解tag helper ,这东西就是element上的 ...

  4. export与export default exports与module.exports的用法

    转载:http://blog.csdn.net/zhou_xiao_cheng/article/details/52759632 本文原创地址链接:http://blog.csdn.net/zhou_ ...

  5. SqlServer和Oracle判断表和列是否存在

    SqlServer .判断表Users是否存在 if object_id(N'Users',N'U') is not null print '存在' else print '不存在' .判断表User ...

  6. Oracle 千万级别数据查询优化

    说明:平时很少接触到大数据分页,今天有兴趣在数据库插入1000万条数据进行测试,经过查询相关资料得到如下说明:笔者在工作中有一上百万条记录的表,在jsp页面中需对该表进行分页显示,便考虑用rownum ...

  7. Python的url解析库--urlparse

    一.urlparse解析url的query并构建字典 下面的方法主要的功能: 解析url的各个部分,并能够获取url的query部分,并把query部分构建成dict. 具体的代码实现: >&g ...

  8. hdu2510 爆搜+打表

    符号三角形 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  9. POJ-1160 Post Office (DP+四边形不等式优化)

    题目大意:有v个村庄成直线排列,要建设p个邮局,为了使每一个村庄到离它最近的邮局的距离之和最小,应该怎样分配邮局的建设,输出最小距离和. 题目分析:定义状态dp(i,j)表示建设 i 个邮局最远覆盖到 ...

  10. The working copy needs to be upgraded svn: The working copy at

    错误信息: The working copy needs to be upgradedsvn: The working copy at 'F:\JAVA Project\PAW-VRVEIS-JJ-2 ...