通过设置优先级来执行线程执行

时间:2015-03-31 17:27:13

标签: java multithreading

我已按以下顺序设置了线程的优先级

A然后是B然后C。但是当我在程序下运行时,有时B在A之前运行。 我不理解这次执行,因为我将B的优先级设置为低于A的优先级。

public class AThread implements Runnable{
    public void run(){
    System.out.println("In thread A");
   }}

  public class BThread implements Runnable {
      public void run(){
    System.out.println("In thread B");  
    } 
   }

 public class CThread implements Runnable {

 public void run(){

    System.out.println("In thread C");

 }

}


 public class ThreadPriorityDemo {

   public static void main(String args[]){

    AThread A = new AThread();
    Thread tA = new Thread(A);


    BThread B = new BThread();
    Thread tB = new Thread(B);

    CThread C = new CThread();
    Thread tC = new Thread(C);

    tA.setPriority(Thread.MAX_PRIORITY);
    tC.setPriority(Thread.MIN_PRIORITY);
    tB.setPriority(tA.getPriority() -1);


    System.out.println("A started");
    tA.start();

    System.out.println("B started");
    tB.start();

    System.out.println("C started");
    tC.start();

}       

}

3 个答案:

答案 0 :(得分:3)

线程优先级可能不是您认为的那样。

线程的优先级是建议操作系统在涉及这两个线程的任何调度或CPU分配决策点中优先选择一个线程而不是另一个线程。但是如何实现它取决于操作系统和JVM实现。

JavaMex对线程优先级进行了很好的讨论。要点是:

  1. 优先事项可能根本没有效果。
  2. 优先级只是一个计算的一部分,用于指示计划。
  3. 在实践中,可以将不同的Java优先级值转换为相同的值(例如,优先级10和9可能相同)。
  4. 每个操作系统都会自行决定如何处理优先级,因为Java正在使用底层操作系统的线程机制。
  5. 请务必阅读下一篇文章,其中将向您展示它在Linux和Windows上的完成情况。

    认为你的问题可能源于上面的第三点(如果你在Windows上运行),但可能是其他任何原因。

答案 1 :(得分:3)

如果您需要执行具有确切顺序的线程,则无法使用线程优先级执行此操作。您可以使用其中一个同步支持。 (例如锁,信号量)。

答案 2 :(得分:2)

我认为正确答案是:您无法通过设置线程优先级来可靠地命令线程启动。

我认为你的困惑源于documentation

的事实
  

优先级较高的线程优先于线程执行   优先级较低。

虽然这是真的,但它只涉及正在进行计算的线程(或者,在某些操作系统上,等待共享资源)。在这种情况下,具有较高优先级的线程将获得更多的CPU时间,即优先于竞争相同资源的线程执行。

即使线程优先级会影响线程的启动顺序(很可能不会),所有线程实际上都可以在现代CPU上并行运行,因为它们不会影响每个线程其他

事实上,执行的顺序完全取决于其他因素:线程不进行任何相关计算,他们花费大部分(非常小的)执行时间等待共享资源,即{{ 1}}。

必须查看代码才能找到基于System.out的代码,System.out实际上atomic, synchronized writes

PrintStream

所发生的是,到达public void write(byte buf[], int off, int len) { try { synchronized (this) { ensureOpen(); out.write(buf, off, len); if (autoFlush) out.flush(); } } catch (InterruptedIOException x) { Thread.currentThread().interrupt(); } catch (IOException x) { trouble = true; } } 的第一个线程阻塞所有其他线程,直到完成写入其输出。无论优先级如何,第一个线程都会蜿蜒,因为您不能中断同步块(这会破坏监视器的用途)。

哪个线程首先获取锁定取决于更多因素而不仅仅是线程优先级,甚至可能根本不取决于(Java)线程优先级。