2012-05-29 93 views
4

我是新来的Java和threads..I的世界,通过一个示例代码正要如下: -理解 “优先级”,在Java线程

package com.alice.learnthread; 

class NewThread implements Runnable{ 
Thread t; 
long clicker=0; 

private volatile boolean running=true; 
NewThread(int p){ 
    t=new Thread(this); 
    t.setPriority(p); 
} 
public void run(){ 
    while(running){ 
     clicker++; 
    } 
} 
public void stop(){ 
    running=false; 
} 
public void start(){ 
    t.start(); 
} 

}

public class TestThread { 
public static void main(String[] args){ 
    Thread r=Thread.currentThread(); 
    r.setPriority(Thread.MAX_PRIORITY); 
    NewThread hi=new NewThread(Thread.NORM_PRIORITY+2); 
    NewThread lo=new NewThread(Thread.NORM_PRIORITY-2); 
    hi.start(); 
    lo.start(); 
    try{ 
     r.sleep(5000); 
    }catch(InterruptedException e){ 
     System.out.println("caught"); 
    } 
    hi.stop(); 
    lo.stop(); 
    try{ 
     hi.t.join(); 
     lo.t.join(); 
    }catch(InterruptedException e){ 
     System.out.println("cau1"); 
    } 
    System.out.println("hi = "+hi.clicker+" lo="+lo.clicker); 
} 

}

但是根据本书的输出结果,具有高优先级的线程应该具有较高的变量答题器值。但在我的情况下,该变量唱首歌值是比更高的优先级one.The输出就像下面我低优先级的线程要高得多: -

hi = 2198713135 lo=2484053552 

这是否并不意味着低优先级的线程获得更多的CPU时间比更高的优先级...我缺少的东西..结果是相同的(对较低的优先级线程更高的喀value声值)在Ubuntu和WIN7 ...

+3

2个线程每一个可能有自己的CPU内核,从来就没有将涉及优的争夺。我猜如果你有10个线程,你可能会看到预期的行为。但即使如此,Java线程调度程序比抢先式更合作,所以如果没有明确的'yield()'调用,您可能仍会得到“有趣”的结果。 –

+0

除了上面的内容,对于你的问题的答案是“这不是说较低优先级的线程比较高优先级的线程获得了更多的CPU时间......”是..不。 –

+0

@鹤山那是什么意思? – Rasmus

回答

2

正如sul所言,优先级更多的是一个暗示,而不是JVM的契约。 在你的情况,你的结果可以通过几种理论来解释:

  • 第二个线程运行得更快,因为它需要的第一个汇编的好处,第一个后停止。
  • while循环检查volatile变量的值强制jvm实现该值,在此期间可能会给其他线程提供CPU。
  • 停止方法花费大量时间来停止线程。

这只是一些事实,可以说线程行为是不可预测的。例如,尝试先启动低优先级的线程,我相信你会得到不同的结果。

而且,试试这个:

public class TestThread 
{ 
    public static void main(String[] args){ 
     Thread r=Thread.currentThread(); 
     r.setPriority(Thread.MAX_PRIORITY); 
     NewThread hi=new NewThread(Thread.MAX_PRIORITY); 
     NewThread lo=new NewThread(Thread.MIN_PRIORITY); 
     hi.start(); 
     lo.start(); 
     try{ 
      r.sleep(5000); 
     }catch(InterruptedException e){ 
      System.out.println("caught"); 
     } 
     hi.interrupt(); 
     lo.interrupt(); 

     System.out.println("hi="+hi.clicker); 
     System.out.println("lo="+lo.clicker); 
    } 
} 
class NewThread extends Thread{ 
    long clicker=0; 

    NewThread(int p){ 
     setPriority(p); 
    } 
    public void run(){ 
     while(true){ 
      clicker++; 
     } 
    } 
} 

我相信,除去挥发性变量和更改线程如何停止会给你一个其他的结果。

+0

感谢您的明确解释 – Rasmus

+1

您应该有一个其他更改是使while循环isInterupted()而不是true。 –

0

线程在本质上不可预测的。低优先级线程在高优先级线程由于某些原因而无法运行时运行,此外,当所有线程都竞争CPU时,线程优先级并不十分有意义。

但是,当我执行上面的程序,我得到了你的书中提到的理想结果。

hi = 1707497920 lo=1699648942 

hi = 1702682202 lo=1685457297 
0

我发现在Windows 7上,如果我增加线程的数量,那里是对系统资源的实际斗争,增加跑的时间点,高优先级的线程执行的顺序更多的点击量。如果情况并非如此,会好奇。我认为你的测试用例在线程数量上太少,以至于无法使用足够的资源来争夺它们,并且还会在运行时让JVM绑定到本地线程。

public static void main(String[] args) { 
     Thread r = Thread.currentThread(); 
     r.setPriority(Thread.MAX_PRIORITY); 
     List<NewThread> hiThreads = new LinkedList<NewThread>(); 
     List<NewThread> lowThreads = new LinkedList<NewThread>(); 
     for (int i = 0; i < 10; i++) { 
      NewThread hi = new NewThread(Thread.NORM_PRIORITY + 2); 
      NewThread lo = new NewThread(Thread.NORM_PRIORITY - 2); 
      hiThreads.add(hi); 
      lowThreads.add(lo); 
      hi.start(); 
      lo.start(); 
     } 
     try { 
      r.sleep(30000); 
     } catch (InterruptedException e) { 
      System.out.println("caught"); 
     } 
     for (NewThread h : hiThreads) { 
      h.stop(); 
     } 
     for (NewThread l : lowThreads) { 
      l.stop(); 
     } 
     try { 
      for (NewThread h : hiThreads) { 
       h.t.join(); 
      } 
      for (NewThread l : lowThreads) { 
       l.t.join(); 
      } 
     } catch (InterruptedException e) { 
      System.out.println("cau1"); 
     } 
     long hiClicker = 0l; 
     for (NewThread h : hiThreads) { 
      hiClicker += h.clicker; 
     } 
     long lowClicker = 0l; 
     for (NewThread l : lowThreads) { 
      lowClicker += l.clicker; 
     } 
     System.out.println("hi = " + hiClicker + " lo=" + lowClicker); 
    } 
0

只是为那些谁寻求多一点的解释... 以下是“完全参考,Java中的摘录,Herbert Shieldt“

作为绝对值,优先级是无意义的;如果它是唯一运行的线程,则优先级更高的线程的运行速度不会低于优先级更低的线程。 相反,线程的优先级用于决定何时从一个正在运行的线程切换到下一个线程。这被称为上下文切换。确定上下文切换何时发生的规则很简单:

  • 线程可以自动放弃控制权。这通过显式地 产生,休眠或阻塞待处理的I/O来完成。在这种情况下,将检查所有其他 线程,并且已准备好运行的最高优先级线程在给定CPU的情况下为 。
  • 线程可以被更高优先级的线程抢占。在这种情况下,不会产生处理器的优先级较低的线程将被优先级较高的线程简单地抢占,而不管它在做什么。基本上,尽快 作为一个更高优先级的线程想运行,它的确如此。这就是所谓的抢占多任务