深入浅出 Java Concurrency (28): 线程池 part 1 简介[转]
从这一节开始正式进入线程池的部分。其实整个体系已经拖了很长的时间,因此后面的章节会加快速度,甚至只是一个半成品或者简单化,以后有时间的慢慢补充、完善。
其实线程池是并发包里面很重要的一部分,在实际情况中也是使用很多的一个重要组件。
下图描述的是线程池API的一部分。广义上的完整线程池可能还包括Thread/Runnable、Timer/TimerTask等部分。这里只介绍主要的和高级的API以及架构和原理。
![]()
大多数并发应用程序是围绕执行任务(Task)进行管理的。所谓任务就是抽象、离散的工作单元(unit of work)。把一个应用程序的工作(work)分离到任务中,可以简化程序的管理;这种分离还在不同事物间划分了自然的分界线,可以方便程序在出现错误时进行恢复;同时这种分离还可以为并行工作提供一个自然的结构,有利于提高程序的并发性。[1]
并发执行任务的一个很重要前提是拆分任务。把一个大的过程或者任务拆分成很多小的工作单元,每一个工作单元可能相关、也可能无关,这些单元在一定程度上可以充分利用CPU的特性并发的执行,从而提高并发性(性能、响应时间、吞吐量等)。
所谓的任务拆分就是确定每一个执行任务(工作单元)的边界。理想情况下独立的工作单元有最大的吞吐量,这些工作单元不依赖于其它工作单元的状态、结果或者其他资源等。因此将任务尽可能的拆分成一个个独立的工作单元有利于提高程序的并发性。
对于有依赖关系以及资源竞争的工作单元就涉及到任务的调度和负载均衡。工作单元的状态、结果或者其他资源等有关联的工作单元就需要有一个总体的调度者来协调资源和执行顺序。同样在有限的资源情况下,大量的任务也需要一个协调各个工作单元的调度者。这就涉及到任务执行的策略问题。
任务的执行策略包括4W3H部分:
- 任务在什么(What)线程中执行
- 任务以什么(What)顺序执行(FIFO/LIFO/优先级等)
- 同时有多少个(How Many)任务并发执行
- 允许有多少个(How Many)个任务进入执行队列
- 系统过载时选择放弃哪一个(Which)任务,如何(How)通知应用程序这个动作
- 任务执行的开始、结束应该做什么(What)处理
在后面的章节中会详细分写这些策略是如何实现的。我们先来简单回答些如何满足上面的条件。
- 首先明确一定是在Java里面可以供使用者调用的启动线程类是Thread。因此Runnable或者Timer/TimerTask等都是要依赖Thread来启动的,因此在ThreadPool里面同样也是靠Thread来启动多线程的。
- 默认情况下Runnable接口执行完毕后是不能拿到执行结果的,因此在ThreadPool里就定义了一个Callable接口来处理执行结果。
- 为了异步阻塞的获取结果,Future可以帮助调用线程获取执行结果。
- Executor解决了向线程池提交任务的入口问题,同时ScheduledExecutorService解决了如何进行重复调用任务的问题。
- CompletionService解决了如何按照执行完毕的顺序获取结果的问题,这在某些情况下可以提高任务执行的并发,调用线程不必在长时间任务上等待过多时间。
- 显然线程的数量是有限的,而且也不宜过多,因此合适的任务队列是必不可少的,BlockingQueue的容量正好可以解决此问题。
- 固定任务容量就意味着在容量满了以后需要一定的策略来处理过多的任务(新任务),RejectedExecutionHandler正好解决此问题。
- 一定时间内阻塞就意味着有超时,因此TimeoutException就是为了描述这种现象。TimeUnit是为了描述超时时间方便的一个时间单元枚举类。
- 有上述问题就意味了配置一个合适的线程池是很复杂的,因此Executors默认的一些线程池配置可以减少这个操作。
线程池的基本策略大致就这些,从下一节开始就从线程池的基本原理和执行方法开始描述。
[1] Java Concurrency in Practice
深入浅出 Java Concurrency (28): 线程池 part 1 简介[转]的更多相关文章
- 深入浅出 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 (36): 线程池 part 9 并发操作异常体系[转]
并发包引入的工具类很多方法都会抛出一定的异常,这些异常描述了任务在线程池中执行时发生的例外情况,而通常这些例外需要应用程序进行捕捉和处理. 例如在Future接口中有如下一个API: java.uti ...
- 深入浅出 Java Concurrency (30): 线程池 part 3 Executor 生命周期[转]
我们知道线程是有多种执行状态的,同样管理线程的线程池也有多种状态.JVM会在所有线程(非后台daemon线程)全部终止后才退出,为了节省资源和有效释放资源关闭一个线程池就显得很重要.有时候无法正确的关 ...
- 深入浅出 Java Concurrency (29): 线程池 part 2 Executor 以及Executors[转]
Java里面线程池的顶级接口是Executor,但是严格意义上讲Executor并不是一个线程池,而只是一个执行线程的工具.真正的线程池接口是ExecutorService. 下面这张图完整描述了线程 ...
- 线程池是什么?Java四种线程池的使用介绍
使用线程池的好处有很多,比如节省系统资源的开销,节省创建和销毁线程的时间等,当我们需要处理的任务较多时,就可以使用线程池,可能还有很多用户不知道Java线程池如何使用?下面小编给大家分享Java四种线 ...
- Java并发编程——线程池的使用
在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统 ...
- Java 多线程:线程池
Java 多线程:线程池 作者:Grey 原文地址: 博客园:Java 多线程:线程池 CSDN:Java 多线程:线程池 工作原理 线程池内部是通过队列结合线程实现的,当我们利用线程池执行任务时: ...
随机推荐
- sklearn中模型评估和预测
一.模型验证方法如下: 通过交叉验证得分:model_sleection.cross_val_score(estimator,X) 对每个输入数据点产生交叉验证估计:model_selection.c ...
- 各种图片特效,你想要吗?你不是真的想要吧?【纯CSS实现】
html部分: <!DOCTYPE html> <html lang="en" class="no-js"> <head> ...
- Unable to resolve dependency for ':app@debug/compileClasspath': Could not resolve com.android.support:appcompat-v7:26.1.0
android studio 3.0 出现此问题可能是因为 你的android studio 时脱机状态 无法下载资源 这时候你可以点击左上角分File->Other Settings-> ...
- Python: 生成器与迭代 generators and iteration
https://eastlakeside.gitbooks.io/interpy-zh/content/Generators/ 文章不是非常好 1,三个概念 可迭代对象 iterable, 迭代器 i ...
- Windows start
启动一个单独的窗口以运行指定的程序或命令. START ["title"] [/D path] [/I] [/MIN] [/MAX] [/SEPARATE | /SHARED] ...
- 0914CSP-S模拟测试赛后总结
9-16 16:03-upd:T3数据出锅,老师重测了,于是更了榜单. 名次并没有变化,但是和大佬们的差距变大了. 还是自己实力不行啊.最起码T3不是特别难想吧. 继续努力吧. 粘个榜:%%%二营长. ...
- clipboard.js操作剪贴版——一些移动端交互和兼容经验
https://github.com/zenorocha/clipboard.js 库,真的是个好库,而且不依赖flash,几乎完美支持移动端.但是,移动端应用有些不趟不知的小tip,这里归档下. 原 ...
- 微信小程序 tabBar模板
tabBar导航栏 小程序tabBar,我们可以通过app.json进行配置,可以放置于顶部或者底部,用于不同功能页面的切换,挺好的... 但,,,貌似不能让动态修改tabBar(需求:通过switc ...
- Berlin Programming Contest 2004 Heavy Transportation /// dijkstra oj22604
题目大意: 输入t:t为样例数 每个样例输入n,m:n 为顶点个数 m 为路径数 接下来m行 每行输入 u v w :从 u 点到 v 点的路承重为 w 输出 车子若想通过 1~n的最短路 车重需限 ...
- vue 利用intersectionOberver实现全局appear/disappear事件
搬运自:https://juejin.im/post/5cd10959f265da03a00fe5c6 效果: demo地址: https://codepen.io/deepkolos/pen/OYP ...