Executor与Task的耦合性

1,除非线程池很非常大,否则一个Task不要依赖同一个线程服务中的另外一个Task,因为这样容易造成死锁;

2,线程的执行是并行的,所以在设计Task的时候要考虑到线程安全问题。如果你认为只会在单任务线程的Executor中运行的话,从设计上讲这就已经耦合了。

3,长时间的任务有可能会影响到其他任务的执行效率,可以让其他线程在等待的时候限定一下等待时间。不要无限制地等待下去。

确定线程池的大小

给出如下定义:

要使CPU达到期望的使用率,线程池的大小应设置为:

约等于Ncpu+1。

定制线程池

通过Executor来创建的线程池其实是预先给我们打造好的线程池,例如:

如果不能满足需求,可以自己量身定做:

  1. public ThreadPoolExecutor(int corePoolSize, //基本大小,没有执行任务时线程池的大小
  2. int maximumPoolSize, //最大任务数量
  3. long keepAliveTime, //最大空闲时间,超时后会被回收
  4. TimeUnit unit,
  5. BlockingQueue<Runnable> workQueue) {
  6. //...
  7. }

任务队列:缓存任务

前面有说到,使用线程池的好处是可以限制线程的数量,因此保证服务器不会被超量的线程给拖垮。当并发请求增加,我们不再是盲目地创建线程了。而是简单地创建一个任务缓存到处理队列中了。那么问题来了,当并发请求继续激增,服务线程无法消化任务,造成大量的任务堆积到队列中。这也是会消耗服务器资源的。

我们需要让服务器实在忙不过来的时候,扔掉一些请求。以保证自己不会奔溃。该放手的时候一定要放手,不是每个人都能随随便便造一个航天飞船发上天啊。服务器真的应付不过来的时候最重要的是要保护好自己。

创建线程池的时候,可以自己指定任务队列:

无界队列:就是创建队列的时候不设置大小;

有界队列:通上设置一个大小;

同步交换队列: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. python之web开发利器

    http://docs.jinkan.org/docs/flask/ https://www.djangoproject.com/

  2. 如何修改路由器的登录IP地址?

    如何修改路由器的登录IP地址? 因为有多个路由器,为了区分不同路由器,我们可以修改它的登录IP,而且修改后,可以在连接的电脑上直观地知道所连接的是哪一台路由器 买回来的路由器,一般默认的登录地址是19 ...

  3. 卡特尔16PF性格测试与答案

    大学生在职业生涯规划时,必须充分注意到自己的性格和职业的适宜性.性格是指一个人在生活中形成的对现实的稳定的态度和行为方式.研究表明,性格影响着一个人的职业取向,由于性格的不同,每个人对工作和职业的态度 ...

  4. 2018.08.09洛谷P3959 宝藏(随机化贪心)

    传送门 回想起了自己赛场上乱搜的20分. 好吧现在也就是写了一个随机化贪心就水过去了,不得不说随机化贪心大法好. 代码: #include<bits/stdc++.h> using nam ...

  5. Part 2 - Fundamentals(4-10)

    https://simpleisbetterthancomplex.com/series/2017/09/11/a-complete-beginners-guide-to-django-part-2. ...

  6. python-optparse模块给脚本增加参数选项

    import optparse parser = optparse.OptionParser('[-] Usage %prog '+ '-H <RHOST[s]> -l [-p -F ]' ...

  7. SwapBuffers的等待,虚伪的FPS(转)

    FPS在实时渲染中扮演着一个重要的角色,也许你会去笑一个不懂FPS是什么的游戏新手,但也许,这只是五十步笑一百步罢了.你能读懂SwapBuffers的深情等待吗?——ZwqXin.com frames ...

  8. 一起学习MVC(3)Views的学习

          _ViewStart.cshtml._Layout.cshtml.Index.cshtml三个页面加载时候的先后顺序就是: _Layout.cshtml ViewStart.cshtml ...

  9. hbase启动异常的慢

    hbase启动慢 hbase启动非常慢,要几个小时,查看日志,发现有如下异常信息: 2016-12-02 22:39:09,365 ERROR [RS_LOG_REPLAY_OPS-db-dn001: ...

  10. Unity Shader 阶段性反思与总结(一)

    Unity Shader 阶段性反思与总结(一) 最近在写Shader的时候,总是感觉力不从心,感觉自己已经看了蛮久的书了,也有一定的积累了,但是一想写什么效果,完完全全就是脑袋一团空白.典型的例子就 ...