Java并发编程实践读书笔记(5) 线程池的使用
Executor与Task的耦合性
1,除非线程池很非常大,否则一个Task不要依赖同一个线程服务中的另外一个Task,因为这样容易造成死锁;
2,线程的执行是并行的,所以在设计Task的时候要考虑到线程安全问题。如果你认为只会在单任务线程的Executor中运行的话,从设计上讲这就已经耦合了。
3,长时间的任务有可能会影响到其他任务的执行效率,可以让其他线程在等待的时候限定一下等待时间。不要无限制地等待下去。
确定线程池的大小
给出如下定义:
要使CPU达到期望的使用率,线程池的大小应设置为:
约等于Ncpu+1。
定制线程池
通过Executor来创建的线程池其实是预先给我们打造好的线程池,例如:
如果不能满足需求,可以自己量身定做:
public ThreadPoolExecutor(int corePoolSize, //基本大小,没有执行任务时线程池的大小
int maximumPoolSize, //最大任务数量
long keepAliveTime, //最大空闲时间,超时后会被回收
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
//...
}
任务队列:缓存任务
前面有说到,使用线程池的好处是可以限制线程的数量,因此保证服务器不会被超量的线程给拖垮。当并发请求增加,我们不再是盲目地创建线程了。而是简单地创建一个任务缓存到处理队列中了。那么问题来了,当并发请求继续激增,服务线程无法消化任务,造成大量的任务堆积到队列中。这也是会消耗服务器资源的。
我们需要让服务器实在忙不过来的时候,扔掉一些请求。以保证自己不会奔溃。该放手的时候一定要放手,不是每个人都能随随便便造一个航天飞船发上天啊。服务器真的应付不过来的时候最重要的是要保护好自己。
创建线程池的时候,可以自己指定任务队列:
无界队列:就是创建队列的时候不设置大小;
有界队列:通上设置一个大小;
同步交换队列:SynchronousQueue,严格意义上说,它并不是真的队列,它只是一种数据交换的工具。任务来之后,这个队列直接把任务交给线程池中的一个线程。如果没有可用线程,则创建一个线程。如果不能创建了会拒绝这个任务。同步交换队列的核心就是它不缓存任务,要么线程池足够大,要么就直接拒绝。用于线程池可以无限增长或不会出现任务激增的场景。
可以用PriorityBlockingQueue来实现任务的排序。
饱和策略:任务队列中都存不了了怎么办
线程池提供了多种处理办法:
Abort:终止,对外抛RejectedExecutionException;
Discard:悄悄抛弃,注意是悄悄地,客户端根本不会知道自己提交的任务根本就没运行;
DiscardOldest:抛弃最老的,如果使用的是优先队列,被抛弃的会是优先级最高的那个(所以DiscardOldest不要和优先队列搭配使用)。
Caller-Runs:用客户端线程来直接运行任务代码。就是哪个线程在往线程池扔任务,那么就用这个线程来直接跑这个任务。这么做的好处是,让客户端分担线程池的负担,更主要的是让客户端先忙一会儿别的,从而暂停往线程池提交任务的动作。以期望线程池能最终缓过来。客户端都来帮着线程池做事了,那它自己的事肯定也就没人做了。如果客户端代码是一个Web请求处理程序,那么它将不再accpet新的请求,这些新的请求会被堵在TCP的缓存中,如果系统一直没有缓过劲来,再继续发展下去,就会把“过载”的信息弥漫到TCP的调用端了。整个这套设计的潜台词是“我们已经尽力了”。系统不会硬着陆直接挂掉,如果请求压力放缓,系统还是可以扛过来的。
线程工厂:定制线程
可以自己实现线程工厂来构建线程变量,从而定义更多需要的信息。
扩展ThreadPoolExecutor
ThreadPoolExecutor有一些生命周期的方法:beforeExecute、afterExecute和terminated。可以重写这些方法,实现统计和监控的功能。
递归算法的并行化
什么样的情况可以并行?
比如for循环去做一些事情,而这些事情是相互独立的。那么这些事情其实可以并行来做的(for循环是串行执行)。
这给我们的编程提供了新的思路,很多写了很多遍、平淡无奇的代码其实有更有趣的实现方式。
Java并发编程实践读书笔记(5) 线程池的使用的更多相关文章
- Java并发编程实践(读书笔记) 任务执行(未完)
任务的定义 大多数并发程序都是围绕任务进行管理的.任务就是抽象和离散的工作单元. 任务的执行策略 1.顺序的执行任务 这种策略的特点是一般只有按顺序处理到来的任务.一次只能处理一个任务,后来其它任 ...
- Java并发编程实践读书笔记(3)任务执行
类似于Web服务器这种多任务情况时,不可能只用一个线程来对外提供服务.这样效率和吞吐量都太低. 但是也不能来一个请求就创建一个线程,因为创建线程的成本很高,系统能创建的线程数量是有限的. 于是Exec ...
- Java并发编程实践读书笔记(1)线程安全性和对象的共享
2.线程的安全性 2.1什么是线程安全 在多个线程访问的时候,程序还能"正确",那就是线程安全的. 无状态(可以理解为没有字段的类)的对象一定是线程安全的. 2.2 原子性 典型的 ...
- Java并发编程实践读书笔记(2)多线程基础组件
同步容器 同步容器是指那些对所有的操作都进行加锁(synchronize)的容器.比如Vector.HashTable和Collections.synchronizedXXX返回系列对象: 可以看到, ...
- Java并发编程实践读书笔记(4)任务取消和关闭
任务的取消 中断传递原理 Java中没有抢占式中断,就是武力让线程直接中断. Java中的中断可以理解为就是一种简单的消息机制.某个线程可以向其他线程发送消息,告诉你“你应该中断了”.收到这条消息的线 ...
- Java并发编程(您不知道的线程池操作)
Java并发编程(您不知道的线程池操作) 这几篇博客,一直在谈线程,设想一下这个场景,如果并发的线程很多,然而每个线程如果执行的时间很多的话,这样的话,就会大量的降低系统的效率.这时候就可以采用线程池 ...
- Java并发编程(您不知道的线程池操作), 最受欢迎的 8 位 Java 大师,Java并发包中的同步队列SynchronousQueue实现原理
Java_并发编程培训 java并发程序设计教程 JUC Exchanger 一.概述 Exchanger 可以在对中对元素进行配对和交换的线程的同步点.每个线程将条目上的某个方法呈现给 exchan ...
- Java并发编程实战 读书笔记(二)
关于发布和逸出 并发编程实践中,this引用逃逸("this"escape)是指对象还没有构造完成,它的this引用就被发布出去了.这是危及到线程安全的,因为其他线程有可能通过这个 ...
- 《Java并发编程实战》第八章 线程池的使用 读书笔记
一.在任务与运行策略之间的隐性解耦 有些类型的任务须要明白地指定运行策略,包含: . 依赖性任务.依赖关系对运行策略造成约束.须要注意活跃性问题. 要求线程池足够大,确保任务都能放入. . 使用线程封 ...
随机推荐
- Json和XML解析
NSXMLParse 关于XML,有两种解析方式,分别是SAX(Simple API for XML,基于事件驱动的解析方式,逐行解析数据,采用协议回调机制)和DOM(Document Object ...
- sklearn中的分词函数countVectorizer()的改动--保留长度为1的字符串
1简述问题 使用countVectorizer()将文本向量化时发现,文本中长度唯一的字符串会被自动过滤掉,这对于我在做的情感分析来讲,一些表较重要的表达情感倾向的词汇被过滤掉,比如文本'没用的东西, ...
- JavaScript 静态方法和实例方法
总结: 直接定义在构造函数上的方法和属性是静态的, 定义在构造函数的原型和实例上的方法和属性是非静态的 静态方法: function ClassA(){ //定义构造函数 }; ClassA.fun ...
- 2018.09.11 bzoj3629: [JLOI2014]聪明的燕姿(搜索)
传送门 一道神奇的搜索. 直接枚举每个质因数的次数,然后搜索就行了. 显然质因数k次数不超过logkn" role="presentation" style=" ...
- 2018.08.30 Tyvj1952 Easy(期望dp)
Description 某一天WJMZBMR在打osu~~~但是他太弱逼了,有些地方完全靠运气:( 我们来简化一下这个游戏的规则 有n次点击要做,成功了就是o,失败了就是x,分数是按comb计算的,连 ...
- phalApi框架打印SQL语句
http://demo.phalapi.net/?service=User.getBaseInfo&user_id=1&__sql__=1
- 关于linux下/srv、/var和/tmp的职责区分
转载自:https://blog.csdn.net/u012107143/article/details/54972544?utm_source=itdadao&utm_medium=refe ...
- (最小生成树)QS Network -- ZOJ --1586
链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1586 http://acm.hust.edu.cn/vjudge/ ...
- java代码中存在的Big Endian 和 Little Endian
Big Endian 和 Little Endian 详解 Java中的Big(Little)-endian问题的一种解决方法 主机序和网络序 很重要很重要 几种ip存放形式 Big-Endian和 ...
- Windows 8/8.1 及 Windows Phone 8 应用神器 - APP Producer
继 App studio 以及 Project Siena 之后 微软再次打造应用生成器 APP Producer,这个版本的应用生成器功能相对比之前两个版本要简单许多,更适合入门并且真正的支持全平 ...