这是一个关于线程优先级的测试。 代码来自 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/