为什么在此示例中,优先级较低的线程不在优先级较高的线程之后执行?



class MyThread extensions Thread {

public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("Child Thread:" + i);
}
}

}

public class ThreadPriorityProperDemo {

public static void main(String[] args) {
MyThread t=new MyThread();
t.setPriority(10);
System.out.println("Main Priority:"+Thread.currentThread().getPriority());
System.out.println("Child Priority:"+t.getPriority());
System.out.println("-----------------------------------");
t.start();
for (int i = 0; i < 10; i++) {
System.out.println("Parent Thread:" + i);
}
}

}

理想的输出应该是:

主要优先级:5

儿童优先:10

子线程:0

子线程:1

子线程:2

子线程:3

子线程:4

子线程:5

子线程:6

子线程:7

子线程:8

子线程:9

父线程:0

父线程:1

父线程:2

父线程:3

父线程:4

父线程:5

父线程:6

父线程:7

父线程:8

父线程:9

但是我得到的输出好坏参半..为什么?我在乌布图16.04 LTS上

你在 Oracle 文档中有一个答案元素。

JVM 为 Java 线程定义了十个逻辑优先级, 包括:

java.lang.Thread.MIN_PRIORITY = 1

java.lang.Thread.NORM_PRIORITY = 5

java.lang.Thread.MAX_PRIORITY = 10

JVM可以自由地以它选择的任何方式实现优先级,包括忽略值。

此外,即使 JVM 完全遵守优先级,多核 CPU 也可以并行运行两个线程。
仅当活动线程数超过 CPU 可能同时运行的进程数时,优先级才可见(对于超线程 CPU = 核心 * 按核心的线程数)。

最后,为短任务设置优先级或设置由于前面解释的条件不成立而可能不会真正应用的优先级(您的并发线程数少于 CPU 能够处理的线程数)将对应用程序的性能产生不良影响:

调用 Thread.setPriority 方法可能是一项代价高昂的操作。 轻率的优先级调整会降低性能。

另外,请记住,您的计算机很可能有多个内核,因此它将同时执行多个线程。 执行以下代码:

int cores = Runtime.getRuntime().availableProcessors();

在我的电脑里,我有 8 个内核。因此,Java 最多可以同时执行 8 个线程。 如果要执行具有不同优先级的任务,一个好方法是使用两个不同的线程池。例如:

ExecutorService executorLowPriority = Executors.newFixedThreadPool(2);
ExecutorService executorHighPriority = Executors.newFixedThreadPool(6);

这是参考Kathy Sierra和Bert Bates的OCA/OCP JAVA SE 7 Programmer I&II学习指南。

setPriority() 方法用于 Thread 对象以提供线程 优先级介于 1(低)和 10(高)之间,尽管优先级不是 保证,但并非所有 JVM 都识别 10 个不同的优先级 — 一些 水平实际上可以被视为相等。

在大多数情况下,正在运行的线程的优先级等于或高于 池中优先级最高的线程。这几乎是关于调度的保证 您将从 JVM 规范中获得,因此您永远不能依赖线程优先级来 保证程序的正确行为。

最后一个:

在设计多线程应用程序时,不要依赖线程优先级。 因为线程调度优先级行为无法保证...

如果你只是想获得所需的输出,你可以尝试使用 JOIN():

public class ThreadPriorityProperDemo {
public static void main(String[] args) {
MyThread t = new MyThread();
t.setPriority(10);
System.out.println("Main Priority:" + Thread.currentThread().getPriority());
System.out.println("Child Priority:" + t.getPriority());
System.out.println("-----------------------------------");
t.start();
try {
t.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for (int i = 0; i < 10; i++) {
System.out.println("Parent Thread:" + i);
}
}
}

最新更新