Effective Java 第三版—— 84. 不要依赖线程调度器

Tips
书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code
注意,书中的有些代码里方法是基于Java 9 API中的,因此JDK 最好下载 JDK 9以上的版本。java

Effective Java, Third Edition

84. 不要依赖线程调度器

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

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

保持可运行线程数量较少的主要技术是让每一个线程作一些有用的工做,而后等待更多的工做。 若是线程没有作有用的工做,它们就不该该运行。 就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中最不可移植的功能之一。 经过调整一些线程优先级来调整应用程序的响应性并非不合理的,但它不多是必需的,而且不可移植。 尝试经过调整线程优先级来解决严重的活跃度问题是不合理的。 在你找到并解决根本缘由以前,问题可能会从新出现。this

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

相关文章
相关标签/搜索