Tips

书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code

注意,书中的有些代码里方法是基于Java 9 API中的,所以JDK 最好下载 JDK 9以上的版本。

84. 不要依赖线程调度器

当许多线程可以运行时,线程调度器(thread scheduler)决定哪些线程可以运行以及运行多长时间。任何合理的操作系统都会尝试公平地做出这个决定,但是策略可能会有所不同。因此,编写良好的程序不应该依赖于此策略的细节。任何依赖线程调度器来保证正确性或性能的程序都可能是不可移植的

编写健壮,响应迅速的可移植程序的最佳方法是确保可运行线程的平均数量不会明显大于处理器数量。 这使得线程调度程序几乎没有多少选择:它只是运行可运行的线程,直到它们不再可运行为止。 即使在完全不同的线程调度策略下,程序的行为也不会有太大变化。 请注意,可运行线程的数量与线程总数不同,后者可能要高得多。 正在等待的线程不可运行。

保持可运行线程数量较少的主要技术是让每个线程做一些有用的工作,然后等待更多的工作。 如果线程没有做有用的工作,它们就不应该运行。 就Executor Framework而言(条目 80),这意味着适当调整线程池的大小[Goetz06, 8.2],并保持任务简短,但不要太短,否则分派的开销会损害性能。

线程不应该处于 busy-wait的状态,反复检查等待其状态改变的共享对象。 除了使程序容易受到线程调度程序的变化无常的影响之外,一直处于 busy-wait的状态大大增加了处理器的负担,减少了其他人可以完成的有用工作量。 作为不该做的极端例子,请考虑CountDownLatch的这种不正当的重新实现:

// Awful CountDownLatch implementation - busy-waits incessantly!
public class SlowCountDownLatch {
private int count; public SlowCountDownLatch(int count) {
if (count < 0)
throw new IllegalArgumentException(count + " < 0");
this.count = count;
} public void await() {
while (true) {
synchronized(this) {
if (count == 0)
return;
}
}
} public synchronized void countDown() {
if (count != 0)
count--;
}
}

在我的机器上,当1000个线程在锁存器(latch)上等待时,SlowCountDownLatch比Java的CountDownLatch慢大约十倍。 虽然这个例子看起来有点牵强,但是看到系统中有一个或多个线程不必要地运行,这种情况并不罕见。 性能和可移植性可能会受到影响。

当一个程序因为某些线程没有获得足够的CPU时间而无法正常工作时,不要试图通过调用Thread.yield方法来“修复”这个程序。你可能会成功地使程序在某种程度上工作,但它不会是可移植的。在一个JVM实现上提高性能的相同的yield方法调用,在第二个JVM实现上可能会使性能变差,而在第三个JVM实现上没有任何影响。Thread.yield没有可测试的语义。更好的做法是重构应用程序,以减少并发运行线程的数量。

类似警告适用的相关技术是调整线程优先级。 线程优先级是Java中最不可移植的功能之一。 通过调整一些线程优先级来调整应用程序的响应性并不是不合理的,但它很少是必需的,并且不可移植。 尝试通过调整线程优先级来解决严重的活跃度问题是不合理的。 在你找到并解决根本原因之前,问题可能会重新出现。

总之,不要依赖线程调度器来确定程序的正确性。 由此产生的程序既不健壮也不可移植。 作为推论,不要依赖Thread.yield方法或线程优先级。 这些机制仅仅是对调度器的提示。 可以谨慎地使用线程优先级来提高已经工作的程序的服务质量,但是它们永远不应该用于“修复”几乎不起作用的程序。

Effective Java 第三版—— 84. 不要依赖线程调度器的更多相关文章

  1. Effective Java 第三版——5. 使用依赖注入取代硬连接资源

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  2. 《Effective Java 第三版》目录汇总

    经过反复不断的拖延和坚持,所有条目已经翻译完成,供大家分享学习.时间有限,个别地方翻译得比较仓促,希望有疑虑的地方指出批评改正. 第一章简介 忽略 第二章 创建和销毁对象 1. 考虑使用静态工厂方法替 ...

  3. 《Effective Java 第三版》新条目介绍

    版权声明:本文为博主原创文章,可以随意转载,不过请加上原文链接. https://blog.csdn.net/u014717036/article/details/80588806前言 从去年的3月份 ...

  4. effective Java 第三版学习笔记

    创建对象类型的 1,静态工厂方法代替构造器 静态工厂方法有名称,不容易混乱他的作用 不必再每次调用他的时候创建实例,创建实例的代价是高的,可以重复利用缓存的对象 静态工厂甚至能返回子类对象,例如在接口 ...

  5. 5. Effective Java 第三版——使用依赖注入取代硬连接资源

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  6. Effective Java 第三版——1. 考虑使用静态工厂方法替代构造方法

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  7. Effective Java 第三版——10. 重写equals方法时遵守通用约定

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  8. Effective Java 第三版——11. 重写equals方法时同时也要重写hashcode方法

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  9. Effective Java 第三版——12. 始终重写 toString 方法

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

随机推荐

  1. UVa-156 Ananagrams 反片语【map】【vector】

    题目链接:https://vjudge.net/contest/211547#problem/D 题目大意: 输入一些单词,找出所有满足以下条件的单词:该单词不能通过字母重排,得到输入文本中的另外一些 ...

  2. php手撸轻量级开发(三)composer小白入门

    composer介绍 composer是php的一个依赖管理工具,在项目中声明所依赖的外部工具库,会自动安装这些工具库及所依赖的库文件. 对我等初阶工程狮来说,就是拉别人的代码,用别人的库,一个进阶版 ...

  3. C# 的Chart

    Axis Label 横纵坐标的文字 (比如 0 20 40 ....) Axis Title 横纵坐标的代表什么(比如 Y Axis Title) Chart Area 图标所在位置 Chart P ...

  4. [数据库]Sqlite使用入门

    官网的文档结构十分恶劣,大概翻了一下,提供入门指引. 0. sqlite的安装 根据自身情况,在官网下载32位/64位的dll文件以及sqlite-tools-win32-x86-3240000.zi ...

  5. 牛客国庆集训派对Day1.B.Attack on Titan(思路 最短路Dijkstra)

    题目链接 \(Description\) 给定\(n,m,C\)及大小为\((n+1)(m+1)\)的矩阵\(c[i][j]\).平面上有\((n+1)(m+1)\)个点,从\((0,0)\)编号到\ ...

  6. Spring cloud Eureka错误锦集(一)

    初学Spring cloud的时候,启动Eureka的时候报了下面的错误: com.sun.jersey.api.client.ClientHandlerException: java.net.Con ...

  7. Linux之经典互联网架构

    经典互联网架构 netstat -tulnp |grep 80ss -tulnp|grep 80 前期铺垫: 1. Linux要能上网2. 掌握Linux软件包安装方法2.1 rpm包管理 2.1.1 ...

  8. 考前停课集训 Day1 废

    [友情链接] Day1 今天模拟赛倒数…… 感觉自己菜到爆炸…… 被一个以前初一的倒数爆踩…… 感觉自己白学了. 满分400,自己只有100.真的是倒数第一…… 做了一个T2,其他暴力分全部没有拿到… ...

  9. mybatis查询到count(*)返回值

    resultType="int" <select id="num_List_" parameterType=" xxx" result ...

  10. unity windowEditor平台下鼠标左键控制摄像机的视角

    工作的原因,今天就只写了unity下的鼠标左键控制摄像机的视角左右上下调节:明天,补齐.[有诸多参考,着实是需要多多加油的] using System.Collections; using Syste ...