深入浅出 Java Concurrency (29): 线程池 part 2 Executor 以及Executors[转]
Java里面线程池的顶级接口是Executor,但是严格意义上讲Executor并不是一个线程池,而只是一个执行线程的工具。真正的线程池接口是ExecutorService。
下面这张图完整描述了线程池的类体系结构。
![]()
首先Executor的execute方法只是执行一个Runnable的任务,当然了从某种角度上将最后的实现类也是在线程中启动此任务的。根据线程池的执行策略最后这个任务可能在新的线程中执行,或者线程池中的某个线程,甚至是调用者线程中执行(相当于直接运行Runnable的run方法)。这点在后面会详细说明。
ExecutorService在Executor的基础上增加了一些方法,其中有两个核心的方法:
- Future<?> submit(Runnable task)
- <T> Future<T> submit(Callable<T> task)
这两个方法都是向线程池中提交任务,它们的区别在于Runnable在执行完毕后没有结果,Callable执行完毕后有一个结果。这在多个线程中传递状态和结果是非常有用的。另外他们的相同点在于都返回一个Future对象。Future对象可以阻塞线程直到运行完毕(获取结果,如果有的话),也可以取消任务执行,当然也能够检测任务是否被取消或者是否执行完毕。
在没有Future之前我们检测一个线程是否执行完毕通常使用Thread.join()或者用一个死循环加状态位来描述线程执行完毕。现在有了更好的方法能够阻塞线程,检测任务执行完毕甚至取消执行中或者未开始执行的任务。
ScheduledExecutorService描述的功能和Timer/TimerTask类似,解决那些需要任务重复执行的问题。这包括延迟时间一次性执行、延迟时间周期性执行以及固定延迟时间周期性执行等。当然了继承ExecutorService的ScheduledExecutorService拥有ExecutorService的全部特性。
ThreadPoolExecutor是ExecutorService的默认实现,其中的配置、策略也是比较复杂的,在后面的章节中会有详细的分析。
ScheduledThreadPoolExecutor是继承ThreadPoolExecutor的ScheduledExecutorService接口实现,周期性任务调度的类实现,在后面的章节中会有详细的分析。
这里需要稍微提一下的是CompletionService接口,它是用于描述顺序获取执行结果的一个线程池包装器。它依赖一个具体的线程池调度,但是能够根据任务的执行先后顺序得到执行结果,这在某些情况下可能提高并发效率。
要配置一个线程池是比较复杂的,尤其是对于线程池的原理不是很清楚的情况下,很有可能配置的线程池不是较优的,因此在Executors类里面提供了一些静态工厂,生成一些常用的线程池。
- newSingleThreadExecutor:创建一个单线程的线程池。这个线程池只有一个线程在工作,也就是相当于单线程串行执行所有任务。如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。
- newFixedThreadPool:创建固定大小的线程池。每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。
- newCachedThreadPool:创建一个可缓存的线程池。如果线程池的大小超过了处理任务所需要的线程,那么就会回收部分空闲(60秒不执行任务)的线程,当任务数增加时,此线程池又可以智能的添加新线程来处理任务。此线程池不会对线程池大小做限制,线程池大小完全依赖于操作系统(或者说JVM)能够创建的最大线程大小。
- newScheduledThreadPool:创建一个大小无限的线程池。此线程池支持定时以及周期性执行任务的需求。
- newSingleThreadScheduledExecutor:创建一个单线程的线程池。此线程池支持定时以及周期性执行任务的需求。
在详细讲解ThreadPoolExecutor的时候会具体讨论上述参数配置后的意义和原理。
线程池是一个复杂的任务调度工具,因此它涉及到任务、线程池等的生命周期问题,在下一节中来探讨下这个问题。
深入浅出 Java Concurrency (29): 线程池 part 2 Executor 以及Executors[转]的更多相关文章
- 深入浅出 Java Concurrency (30): 线程池 part 3 Executor 生命周期[转]
我们知道线程是有多种执行状态的,同样管理线程的线程池也有多种状态.JVM会在所有线程(非后台daemon线程)全部终止后才退出,为了节省资源和有效释放资源关闭一个线程池就显得很重要.有时候无法正确的关 ...
- 深入浅出 Java Concurrency (35): 线程池 part 8 线程池的实现及原理 (3)[转]
线程池任务执行结果 这一节来探讨下线程池中任务执行的结果以及如何阻塞线程.取消任务等等. 1 package info.imxylz.study.concurrency.future;2 3 publ ...
- 深入浅出 Java Concurrency (34): 线程池 part 7 线程池的实现及原理 (2)[转]
线程池任务执行流程 我们从一个API开始接触Executor是如何处理任务队列的. java.util.concurrent.Executor.execute(Runnable) Executes t ...
- 深入浅出 Java Concurrency (33): 线程池 part 6 线程池的实现及原理 (1)[转]
线程池数据结构与线程构造方法 由于已经看到了ThreadPoolExecutor的源码,因此很容易就看到了ThreadPoolExecutor线程池的数据结构.图1描述了这种数据结构. 图1 Thre ...
- 深入浅出 Java Concurrency (28): 线程池 part 1 简介[转]
从这一节开始正式进入线程池的部分.其实整个体系已经拖了很长的时间,因此后面的章节会加快速度,甚至只是一个半成品或者简单化,以后有时间的慢慢补充.完善. 其实线程池是并发包里面很重要的一部分,在实际情况 ...
- 深入浅出 Java Concurrency (36): 线程池 part 9 并发操作异常体系[转]
并发包引入的工具类很多方法都会抛出一定的异常,这些异常描述了任务在线程池中执行时发生的例外情况,而通常这些例外需要应用程序进行捕捉和处理. 例如在Future接口中有如下一个API: java.uti ...
- Java并发——ThreadPoolExecutor线程池解析及Executor创建线程常见四种方式
前言: 在刚学Java并发的时候基本上第一个demo都会写new Thread来创建线程.但是随着学的深入之后发现基本上都是使用线程池来直接获取线程.那么为什么会有这样的情况发生呢? new Thre ...
- [转] 多线程 《深入浅出 Java Concurrency》目录
http://ifeve.com/java-concurrency-thread-directory/ synchronized使用的内置锁和ReentrantLock这种显式锁在java6以后性能没 ...
- 《深入浅出 Java Concurrency》目录
最近在学习J.U.C,看到一个大神 关于这个系列写的非常精辟,由于想做笔记,故系列转载并记录之. 原文:http://www.blogjava.net/xylz/archive/2010/07/08/ ...
随机推荐
- KNN 实战
KNN算法很简单,大致的工作原理是:给定训练数据样本和标签,对于某测试的一个样本数据,选择距离其最近的k个训练样本,这k个训练样本中所属类别最多的类即为该测试样本的预测标签.简称kNN.通常k是不大于 ...
- shell 命令 修改文件权限 chmod
1. 所有者+.-权限 更改那个拥有者的权限 u 表示文件的所有者 g 表示文件所在的组 o 表示其他用户 a 所有,以上三者 增加 / 减少权限 + 表示增加权限 - 表示取消权限 更改具体 ...
- dialogs打开对话框选定文件夹,getopenfilename获取文件名
如果需要使用“打开”.“打印”等Excel内置对话框已经具有的功能,可以使用代码直接调用这些内置的对话框,如下面的代码所示. #001 Sub DialogOpen() #002 Appl ...
- SVN Cannot merge into a working copy that has local modifications
我尝试了 主支,分支都提交,但是依然无法合并. 最终,我在服务器上将分支删除,然后主支在拷贝过去. 一,打开服务器资源 二,删除分支 三,拷贝主支到分支 四,刷新分支,就能看到了. 然后在分支项目中, ...
- 去哪儿的 源码 个人解析(2) router
1.引进路由 import Vue from 'vue' 2.使用路由 Vue.use(Router) 3.路由注册 export default new Router({ routes: [{ ...
- 【JZOJ6274】梦境
description analysis 其实可以贪心 先把区间按左端点排序,转折点也排序 扫一次转折点,把所有左端点在当前点左边的区间丢进优先队列里 按照贪心策略,对于某个转折点,一定选择右端点离它 ...
- 0927CSP-S模拟测试赛后总结
84pts rank28 经历了一个阶段的持续低迷,终于回到自己之前的位置了啊. 尽管依旧不是太靠上,但是还是证明了我的努力. 宿舍三人的风水轮流转之谈终究只是戏言和巧合.嘟嘟和Lockey都进第一机 ...
- cf1147
C——筛法 #include<bits/stdc++.h> using namespace std; ]; int main(){ cin>>n; ; ;i<=n;i++ ...
- PAT甲级——A1112 Stucked Keyboard【20】
On a broken keyboard, some of the keys are always stucked. So when you type some sentences, the char ...
- 17.splash_case06_ScrapySplashTest-master
taobao.py # -*- coding: utf-8 -*- from scrapy import Spider, Request from urllib.parse import quote ...