Java线程优先级没有影响

标签 java windows multithreading java-7

这是一个关于线程优先级的测试。 代码来自 Thinking in Java p.809

import java.util.concurrent.*;

public class SimplePriorities implements Runnable {
    private int countDown = 5;
    private volatile double d; // No optimization
    private int priority;

    public SimplePriorities(int priority) {
        this.priority = priority;
    }

    public String toString() {
        return Thread.currentThread() + ": " + countDown;
    }

    public void run() {
        Thread.currentThread().setPriority(priority);
        while (true) {
            // An expensive, interruptable operation:
            for (int i = 1; i < 10000000; i++) {
                d += (Math.PI + Math.E) / (double) i;
                if (i % 1000 == 0)
                    Thread.yield();
            }
            System.out.println(this);
            if (--countDown == 0)
                return;
        }
    }

    public static void main(String[] args) {
        ExecutorService exec = Executors.newCachedThreadPool();
        for (int i = 0; i < 5; i++)
            exec.execute(new SimplePriorities(Thread.MIN_PRIORITY));
        exec.execute(new SimplePriorities(Thread.MAX_PRIORITY));
        exec.shutdown();
    }
}

我想知道为什么我不能得到像这样的常规结果:

Thread[pool-1-thread-6,10,main]: 5 
Thread[pool-1-thread-6,10,main]: 4 
Thread[pool-1-thread-6,10,main]: 3 
Thread[pool-1-thread-6,10,main]: 2 
Thread[pool-1-thread-6,10,main]: 1 
Thread[pool-1-thread-3,1,main]: 5 
Thread[pool-1-thread-2,1,main]: 5 
Thread[pool-1-thread-1,1,main]: 5 
Thread[pool-1-thread-5,1,main]: 5 
Thread[pool-1-thread-4,1,main]: 5 
...

但随机结果(每次我运行它都会改变):

Thread[pool-1-thread-2,1,main]: 5
Thread[pool-1-thread-3,1,main]: 5
Thread[pool-1-thread-4,1,main]: 5
Thread[pool-1-thread-2,1,main]: 4
Thread[pool-1-thread-3,1,main]: 4
Thread[pool-1-thread-1,1,main]: 5
Thread[pool-1-thread-6,10,main]: 5
Thread[pool-1-thread-5,1,main]: 5
...

我使用 i3-2350M 2C4T CPU 和 Win 7 64 位 JDK 7。 重要吗?

最佳答案

Java Thread priority has no effect

线程优先级是高度特定于操作系统的,在许多操作系统上通常影响很小。优先级仅有助于对运行队列中的线程进行排序,并且不会以任何主要方式改变线程运行的频率,除非您在每个线程中执行大量 CPU。

您的程序看起来使用了大量 CPU,但除非您的核心数少于线程数,否则通过设置线程优先级您可能看不到输出顺序有任何变化。如果有空闲的 CPU,那么即使是较低优先级的线程也会被安排运行。

此外,线程永远不会饿死。在这种情况下,即使是较低优先级的线程也会经常运行。您应该看到优先级较高的线程被分配时间片以更频繁地运行,但这并不意味着优先级较低的线程将等待它们完成后再运行。

即使优先级确实有助于为一个线程提供比其他线程更多的 CPU,线程程序仍受制于 race conditions这有助于为它们的执行注入(inject)大量的随机性。然而,您应该看到的是,最高优先级线程比其他线程更有可能更频繁地吐出其 0 消息。如果您将优先级添加到 println(),那么在多次运行后应该会变得很明显。

同样重要的是要注意 System.out.println(...) 是正在写入 IO 的 synchronized 方法,这将显着影响线程的运行方式交互,不同的线程互相阻塞。此外,Thread.yield(); 可以是空操作,具体取决于操作系统如何进行线程调度。

but a random result (every time I run it changes):

没错。线程程序的输出很少“完美”,因为根据定义,线程是异步运行的。我们希望输出是随机的,因为我们希望线程彼此独立地并行运行。那是他们的力量。如果您期望得到一些精确的输出,那么您不应该使用线程。

关于Java线程优先级没有影响,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12038592/

相关文章:

c# - 在 C# 中使用多线程时出现内存不足异常

multithreading - 我如何在Neo4j中使用并行事务?

java - 我的位 vector 有什么问题?

Java无法访问的代码错误

c# - 在没有 System.Windows.Forms 的情况下设置鼠标位置

c++ - 如果 HWND 窗口仍然存在,我该如何确定

java - 对象引用何时会被垃圾回收?

java - 在 Jenkins 中找不到 Spark-version-info.properties

windows - Flutter平台 channel 将 "multi-data"传递给windows函数

C++ 静态类成员指的是自身