Effective Java(3rd)-Item80 与线程相比,更喜欢执行器、任务和流

  这本书的第一版包含了一个简单工作队列的代码[Bloch01,49项)。这个类允许客户端通过后台线程为异步处理排队。当不再需要工作队列时,客户机可以调用一个方法,要求后台线程在完成队列上的任何工作后优雅地终止自己。个实现只不过是一个玩具,但即便如此,它也需要一整页微妙、微妙的代码,如果你做得不对,就很容易出现安全和活性失败。幸运的是,没有理由再编写这种代码了。
  当这本书的第二版出版时,java.util.concurrent已经添加到Java中。这个包包含一个Executor框架,它是一个灵活的基于接口的任务执行工具。创建一个工作队列,在任何方面都比在这本书的第一版更好,只需要一行代码:
ExecutorService exec = Executors.newSingleThreadExecutor();
  下面是如何提交一个可运行的执行:
exec.execute(runnable);
  下面是如何告诉执行器优雅地终止(如果你做不到这一点,你的虚拟机很可能不会退出):
exec.shutdown();
  您可以使用executor service做更多的事情。例如,您可以等待特定的任务完成(使用get方法,如第319页第79项所示),您可以等待任何或所有任务集合完成(使用invokeAny或invokeAll方法),您可以等待executor服务终止(使用awaitterminate方法),您可以在任务完成时一个一个地检索它们的结果(使用ExecutorCompletionService),您可以安排任务在特定的时间运行或定期运行(使用
ScheduledThreadPoolExecutor),等等。
  如果希望多个线程处理来自队列的请求,只需调用一个不同的静态工厂,该工厂创建一种称为线程池的不同类型的执行器服务。您可以使用固定或可变数量的线程创建线程池。java.util.concurrent.Executors类包含静态工厂,这些工厂提供了您需要的大多数执行器。然而,如果你想要一些不同寻常的,您可以直接使用ThreadPoolExecutor类。这个类允许您配置线程池操作的几乎每个方面。
  为特定的应用程序选择executor服务可能比较棘手。对于小程序或负载较轻的服务器,Executors.newCachedThreadPool通常是一个不错的选择,因为它不需要配置,而且通常“做正确的事情”。但是对于负载沉重的生产服务器来说,缓存的线程池不是一个好的选择!在缓存的线程池中,提交的任务不会排队,而是立即传递给线程执行。如果没有可用的线程,则创建一个新的线程。如果服务器负载过重,所有cpu都被充分利用,并且有更多的任务到达,就会创建更多的线程,这只会使情况变得更糟。因此,在负载沉重的生产服务器中,最好使用executor.newFixedThreadPool,它为您提供一个线程数量固定的池,或者直接使用ThreadPoolExecutor类来实现最大限度的控制。
  您不仅应该避免编写自己的工作队列,而且通常还应该避免直接使用线程.当您直接使用线程时,线程既是工作单元,又是执行它的机制。在executor框架中,工作单元和执行机制是分开的。关键的抽象是工作单元,即任务。
有两种任务:Runnable和它的近亲Callable(与Runnable类似,只是它返回一个值并可以抛出任意异常)。执行任务的一般机制是executor service。如果您从任务的角度考虑问题,并让executor服务为您执行这些任务,那么您就可以灵活地选择合适的执行策略来满足您的需求,并在您的需求发生变化时更改策略。本质上,Executor框架执行的功能与Collections框架聚合的功能相同。
  在Java 7中,Executor框架被扩展为支持fork-join任务,它们由一种特殊的执行器服务(称为fork-join池)运行。一个 fork-join任务,由一个ForkJoinTask实例表示,可以分解为更小的子任务,以及包含fork join池的线程不仅仅是进程 这些任务只是互相“窃取”任务,以确保所有线程都保持不变繁忙,导致更高的CPU利用率、更高的吞吐量和更低的延迟。编写和调优fork-join任务非常棘手。并行流(item48 )是在fork连接池之上编写的,假设它们适合当前的任务,那么您可以轻松地利用它们的性能优势。

  对Executor框架的完整处理超出了本书的范围,但是感兴趣的读者可以在 Java Concurrency in Practice接触Java并发[Goetz06]。
本文写于2019.7.23,历时1天

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,723评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,485评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,998评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,323评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,355评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,079评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,389评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,019评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,519评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,971评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,100评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,738评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,293评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,289评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,517评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,547评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,834评论 2 345

推荐阅读更多精彩内容