Effective Java 第三版—— 84. 不要依赖线程调度器
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. 不要依赖线程调度器的更多相关文章
- Effective Java 第三版——5. 使用依赖注入取代硬连接资源
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- 《Effective Java 第三版》目录汇总
经过反复不断的拖延和坚持,所有条目已经翻译完成,供大家分享学习.时间有限,个别地方翻译得比较仓促,希望有疑虑的地方指出批评改正. 第一章简介 忽略 第二章 创建和销毁对象 1. 考虑使用静态工厂方法替 ...
- 《Effective Java 第三版》新条目介绍
版权声明:本文为博主原创文章,可以随意转载,不过请加上原文链接. https://blog.csdn.net/u014717036/article/details/80588806前言 从去年的3月份 ...
- effective Java 第三版学习笔记
创建对象类型的 1,静态工厂方法代替构造器 静态工厂方法有名称,不容易混乱他的作用 不必再每次调用他的时候创建实例,创建实例的代价是高的,可以重复利用缓存的对象 静态工厂甚至能返回子类对象,例如在接口 ...
- 5. Effective Java 第三版——使用依赖注入取代硬连接资源
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- Effective Java 第三版——1. 考虑使用静态工厂方法替代构造方法
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- Effective Java 第三版——10. 重写equals方法时遵守通用约定
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- Effective Java 第三版——11. 重写equals方法时同时也要重写hashcode方法
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- Effective Java 第三版——12. 始终重写 toString 方法
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
随机推荐
- HDU 3342 Legal or Not (图是否有环)【拓扑排序】
<题目链接> 题目大意: 给你 0~n-1 这n个点,然后给出m个关系 ,u,v代表u->v的单向边,问你这m个关系中是否产生冲突. 解题分析: 不难发现,题目就是叫我们判断图中是否 ...
- Mysql8.0升级后,Navicat连接报错caching_sha2_password 问题
需要重新配置加密规则 ALTER USER 'root'@'localhost' IDENTIFIED BY 'password' PASSWORD EXPIRE NEVER; ALTER USER ...
- POJ.2175.Evacuation Plan(消圈)
POJ \(Description\) \(n\)个建筑物,每个建筑物里有\(a_i\)个人:\(m\)个避难所,每个避难所可以容纳\(b_i\)个人. 给出每个建筑物及避难所的坐标,任意两点间的距离 ...
- 2017-9-8-WLW尝试
666 main () { int abc int def } #include<stdio.h> int main() { printf("hello world!\n&quo ...
- 设置字体格式,加粗,regular,light
设置文字大小和字体的途径有两个: 第一种,直接使用xib设置 , , 第二种,使用代码 Label.font = [UIFont fontWithName:.f];//加粗 Label.fo ...
- Java 关键字 static
关键字static作用如下: 1. 为某个基本数据类型或对象分配单一的存储空间. 2. 实现某个属性或方法与类关联.在类被加载后类名可以直接调用静态成员方法(下面简称静态方法)或者访问静态成员变量(下 ...
- 自定义simple_tag和filter在html中渲染出来的联系和区别
关于 simple_tag: 1,在app下创建一个(templatetags)目录,(被引用的模块必须放在该目录下,且目录名称不可更改): 2,创建任意py文件: 3,创建template对象: f ...
- hibernate 的第一个工程
一.什么是Hibernate? Hibernate 是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hiber ...
- 【最大公约数&链表】权值 @upcexam5921
时间限制: 1 Sec 内存限制: 512 MB 题目描述 给定一个长为n的正整数序列Ai.对于它的任意一个连续的子序列{Al, Al+1, …, Ar},定义其权值W (l, r)为其长度与序列中所 ...
- jQuery中动画常用的样式获取并改变方法-
(1)Top 和 left 经常要用到jquery获取对象的位置,jquery top left,jquery css left是相对于父级元素中第一个position为relative或absolu ...