Java 编译器忽略线程优先级

Java 编译器忽略线程优先级,java,multithreading,Java,Multithreading,我试图编译Bruce Eckel用Java思考的示例: 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 priorit

我试图编译Bruce Eckel用Java思考的示例:

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 < 100000; 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();
  }
}

但在我的例子中,第六个线程一开始并没有执行它的任务,线程是无序的。你能解释一下怎么了吗?我只是复制了源代码,没有添加任何代码字符串。

代码运行良好,与书中的输出一致

您的IDE可能有一个带有滚动条的控制台窗口——只需向上滚动它,就可以看到第6个线程首先执行它的工作


但是,结果可能因OS/JVM版本而异。这段代码在Windows 10/JVM 8上按预期运行。代码运行良好,与本书的输出一致

您的IDE可能有一个带有滚动条的控制台窗口——只需向上滚动它,就可以看到第6个线程首先执行它的工作


但是,结果可能因OS/JVM版本而异。这段代码在Windows 10/JVM 8上按预期运行这里有两个问题:

如果两个具有相同优先级的线程要写入输出,哪一个先执行?

线程顺序(具有相同优先级)未定义,因此输出顺序未定义。可能允许单个线程在一行中写入多个输出(因为这是大多数线程调度程序的工作方式),但它也可能是完全随机的,或者介于两者之间的任何东西

缓存的线程池将创建多少个线程?

这取决于你的系统。如果在双核系统上运行,创建4个以上的线程是没有意义的,因为几乎没有任何CPU可用于执行这些线程。在这种情况下,进一步的任务将排队,并仅在先前的任务完成后执行

提示:还有一个固定大小的线程池,尝试使用它应该会改变输出

总之,您的代码没有任何问题,只是假设线程以任何顺序执行是错误的。甚至在技术上,第一个任务在最后一个任务开始之前就已经完成(尽管可能性很小)。如果你的书上说上面的顺序是“正确的”,那么这本书就是错的。在一个平均的系统上,这可能是最有可能的输出,但是——如上所述——对于线程,从来没有任何顺序,除非您强制执行它


执行它的一种方法是线程优先级-更高优先级将首先完成它们的工作-您可以在中找到其他概念。

这里有两个问题:

如果两个具有相同优先级的线程要写入输出,哪一个先执行?

线程顺序(具有相同优先级)未定义,因此输出顺序未定义。可能允许单个线程在一行中写入多个输出(因为这是大多数线程调度程序的工作方式),但它也可能是完全随机的,或者介于两者之间的任何东西

缓存的线程池将创建多少个线程?

这取决于你的系统。如果在双核系统上运行,创建4个以上的线程是没有意义的,因为几乎没有任何CPU可用于执行这些线程。在这种情况下,进一步的任务将排队,并仅在先前的任务完成后执行

提示:还有一个固定大小的线程池,尝试使用它应该会改变输出

总之,您的代码没有任何问题,只是假设线程以任何顺序执行是错误的。甚至在技术上,第一个任务在最后一个任务开始之前就已经完成(尽管可能性很小)。如果你的书上说上面的顺序是“正确的”,那么这本书就是错的。在一个平均的系统上,这可能是最有可能的输出,但是——如上所述——对于线程,从来没有任何顺序,除非您强制执行它


执行它的一种方法是线程优先级-更高优先级将首先完成它们的工作-您可以在中找到其他概念。

确定吗?上次我花了几个小时编写使用线程优先级的代码。。。Linux和各种版本的windows都不关心它们。如果你让这个例子起作用,我真的很感兴趣你正在使用什么JVM和操作系统。我刚刚在我的Windows10电脑上用JVM运行了它。我想我必须研究一下我的实验代码。但是您应该增强您的答案,并指出这可能取决于操作系统和JVM类型/版本。确定吗?上次我花了几个小时编写使用线程优先级的代码。。。Linux和各种版本的windows都不关心它们。如果你让这个例子起作用,我真的很感兴趣你正在使用什么JVM和操作系统。我刚刚在我的Windows10电脑上用JVM运行了它。我想我必须研究一下我的实验代码。但是你应该加强你的答案,并指出这可能取决于操作系统和JVM类型/版本。如果线程优先级正常与否,那么这是独立的-你的问题标题表明了一种误解。编译器编译了您让它编译的内容。这与编译器无关。这只植根于线程在运行时的实现方式。输出的顺序未定义,如果书中说有任何不同,则是错误的。独立于线程优先级是否正常-您的问题标题表示误解。编译器编译了您让它编译的内容。这与编译器无关。这仅仅源于线程在运行时的实现方式。输出的顺序是未定义的,如果书中说有任何不同,那就是错误的。
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
...