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) 线程池的使用的更多相关文章

  1. Java并发编程实践(读书笔记) 任务执行(未完)

    任务的定义 大多数并发程序都是围绕任务进行管理的.任务就是抽象和离散的工作单元.   任务的执行策略 1.顺序的执行任务 这种策略的特点是一般只有按顺序处理到来的任务.一次只能处理一个任务,后来其它任 ...

  2. Java并发编程实践读书笔记(3)任务执行

    类似于Web服务器这种多任务情况时,不可能只用一个线程来对外提供服务.这样效率和吞吐量都太低. 但是也不能来一个请求就创建一个线程,因为创建线程的成本很高,系统能创建的线程数量是有限的. 于是Exec ...

  3. Java并发编程实践读书笔记(1)线程安全性和对象的共享

    2.线程的安全性 2.1什么是线程安全 在多个线程访问的时候,程序还能"正确",那就是线程安全的. 无状态(可以理解为没有字段的类)的对象一定是线程安全的. 2.2 原子性 典型的 ...

  4. Java并发编程实践读书笔记(2)多线程基础组件

    同步容器 同步容器是指那些对所有的操作都进行加锁(synchronize)的容器.比如Vector.HashTable和Collections.synchronizedXXX返回系列对象: 可以看到, ...

  5. Java并发编程实践读书笔记(4)任务取消和关闭

    任务的取消 中断传递原理 Java中没有抢占式中断,就是武力让线程直接中断. Java中的中断可以理解为就是一种简单的消息机制.某个线程可以向其他线程发送消息,告诉你“你应该中断了”.收到这条消息的线 ...

  6. Java并发编程(您不知道的线程池操作)

    Java并发编程(您不知道的线程池操作) 这几篇博客,一直在谈线程,设想一下这个场景,如果并发的线程很多,然而每个线程如果执行的时间很多的话,这样的话,就会大量的降低系统的效率.这时候就可以采用线程池 ...

  7. Java并发编程(您不知道的线程池操作), 最受欢迎的 8 位 Java 大师,Java并发包中的同步队列SynchronousQueue实现原理

    Java_并发编程培训 java并发程序设计教程 JUC Exchanger 一.概述 Exchanger 可以在对中对元素进行配对和交换的线程的同步点.每个线程将条目上的某个方法呈现给 exchan ...

  8. Java并发编程实战 读书笔记(二)

    关于发布和逸出 并发编程实践中,this引用逃逸("this"escape)是指对象还没有构造完成,它的this引用就被发布出去了.这是危及到线程安全的,因为其他线程有可能通过这个 ...

  9. 《Java并发编程实战》第八章 线程池的使用 读书笔记

    一.在任务与运行策略之间的隐性解耦 有些类型的任务须要明白地指定运行策略,包含: . 依赖性任务.依赖关系对运行策略造成约束.须要注意活跃性问题. 要求线程池足够大,确保任务都能放入. . 使用线程封 ...

随机推荐

  1. ejb 和pojo , jboss 和 tomcat

    EJB(企业JavaBeans)是普通JavaBeans的一种提升和规范,因为企业信息系统开发中需要一个可伸缩的性能和事务.安全机制,这样能保证企业系统平滑发展,而不是发展到一种规模重新更换一套软件系 ...

  2. [转载红鱼儿]Delphi实现微信开发(3)如何使用multipart/form-data格式上传文件

    开始前,先看下要实现的微信接口,上传多媒体文件,这个接口是用Form表单形式上传的文件.对我来说,对http的Form表单一知半解,还好,查到这个资料,如果你也和我一样,必须看看这篇文章. 在xali ...

  3. 2018.09.16 loj#10242. 取石子游戏 2(博弈论)

    传送门 同样有一个显然的结论. 如果a1a_1a1​ xorxorxor a2a_2a2​ xorxorxor a3a_3a3​ xor...xor...xor... xorxorxor ana_na ...

  4. 2018.08.16 洛谷P1471 方差(线段树)

    传送门 线段树基本操作. 把那个方差的式子拆开可以发现只用维护一个区间平方和和区间和就可以完成所有操作. 同样区间修改也可以简单的操作. 代码: #include<bits/stdc++.h&g ...

  5. spring 课程

    官网 参考文档 // 1. Spring_HelloWorld 20:22 // 2. Spring_IOC&DI概述 08:07 // 3. Spring_配置 Bean 21:58 // ...

  6. WPF 嵌入字体文件

    官方说明文档:将字体与应用程序一起打包 https://docs.microsoft.com/zh-cn/dotnet/framework/wpf/advanced/packaging-fonts-w ...

  7. ( KMP 求循环节的个数)Power Strings -- poj -- 2406

    链接: http://poj.org/problem?id=2406 Power Strings Time Limit:3000MS     Memory Limit:65536KB     64bi ...

  8. (并查集 贪心思想)Supermarket -- POJ --1456

    链接: http://poj.org/problem?id=1456 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=82830#probl ...

  9. [译]window.onerror事件

    本文翻译youtube上的up主kudvenkat的javascript tutorial播放单 源地址在此: https://www.youtube.com/watch?v=PMsVM7rjupU& ...

  10. hdu3853 LOOPS(概率dp) 2016-05-26 17:37 89人阅读 评论(0) 收藏

    LOOPS Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 125536/65536 K (Java/Others) Total Su ...