为什么具有较低优先级的线程比此代码中具有较高优先级的线程获得更长的CPU时间

时间:2013-07-12 17:11:32

标签: java multithreading thread-priority

我正在阅读Java The complete Reference - Herbert Schildt (TATA McGRAW HILL)中的主题。在这个示例表单中,优先级较低的Thread应该比具有较高优先级的Thread提供较低的clicks值。但我得到了什么

low-priority thread 3000255895
hi-priority thread  2857361716

根据书,它是这样的(差异)

low-priority thread 4408112
hi-priority thread  589626904

class Clicker implements Runnable {
    long click = 0;
    Thread t;
    private volatile boolean running = true;

    public Clicker (int p) {
        t  = new Thread(this);
        t.setPriority(p);
    }

    public void run() {
        while(running) {
            click++;
        }
    }

    public void stop() {
        running = false;
    }

    public void start() {
        t.start();
    }
}

class Priority {
    public static void main(String args[]) {
        Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
        Clicker hi = new Clicker(Thread.NORM_PRIORITY + 2);
        Clicker lo = new Clicker(Thread.NORM_PRIORITY - 2); 
        hi.start();
        lo.start();
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            System.out.println("main thread interrupted");
        }

        lo.stop();
        hi.stop();

        try {
            hi.t.join();
            lo.t.join();
        } catch (InterruptedException e) {
            System.out.println("interrupted exception catched in main");
        }

        System.out.println("low-priority thread " + lo.click);
        System.out.println("hi-priority thread " + hi.click);
    }
}

我在Intel® Core™ i3-2310M CPU @ 2.10GHz × 4 with Ubuntu 13.04

Thread.sleep(50000);

low-priority thread 14849893875
hi-priority thread 14224080358

这不是一个很大的区别

我也尝试优先级HI = 10和LOw = 1,但结果几乎相同。

更新: 运行100个线程50后,priority = 150 with priority = 10结果为

此处time = clicks values

high = 82 time = 110117529
low =  83 time = 102549208
high = 84 time = 110905795
low =  85 time = 99100530
high = 86 time = 105012756
low =  87 time = 110195297
high = 88 time = 102820088
low =  89 time = 97814606
high = 90 time = 99990839
low =  91 time = 102326356
high = 92 time = 98656119
low =  93 time = 98127243
high = 94 time = 97097823
low =  95 time = 103604394
high = 96 time = 93632744
low =  97 time = 99032550
high = 98 time = 103879116
low =  99 time = 97179029

使用1000个主题Take 4-5 min. to complete, all 4 cores at 100%

low =  977 time = 23593983
high = 978 time = 23998970
low =  979 time = 23879458
high = 980 time = 22775297
low =  981 time = 21297504
high = 982 time = 22464600
low =  983 time = 20301501
high = 984 time = 19073992
low =  985 time = 19450707
high = 986 time = 19317769
low =  987 time = 18454648
high = 988 time = 17901939
low =  989 time = 16976661
high = 990 time = 17360728
low =  991 time = 16813824
high = 992 time = 15531501
low =  993 time = 14659965
high = 994 time = 12833364
low =  995 time = 13708670
high = 996 time = 13348568
low =  997 time = 12947993
high = 998 time = 12749436
low =  999 time = 9804643

每个线程的不可预测的输出。

2 个答案:

答案 0 :(得分:2)

我怀疑示例数字在某种程度上取决于您的平台和作者(示例是否运行在单个核心上?)。 JVM线程优先级是特定于OS /平台的。来自this interesting document

  

Linux优先级

     

在Linux下,你必须通过更多的箍来获取线程   最重要的是,尽管最后,它们可能更多   比在Windows下有用。在Linux中:

     
      
  • 线程优先级仅在Java 6之后起作用;
  •   
  • 要让它们工作,您必须以root身份运行(或通过setuid以root权限运行);
  •   
  • JVM参数-XX:必须包含UseThreadPriorities
  •   

请检查您的Java版本,Java调用和您的权限。我怀疑(!)你只满足其中一个标准(你的Java / JVM版本)。

答案 1 :(得分:0)

除了Thread优先级在大多数实现和平台下都是灰色区域之外,您可以查看的其他内容是:

  1. 很可能,click不会包含确切的调用次数。这应该是AtomicLong。那么你想要差异有多大? + -2也没有太大的区别。

  2. 使用MIN_PRIORITY运行一个线程,使用MAX_PRIORITY运行其他线程。计算差异。用10,100,1000个线程重复上述实验。其中50%使用MIN_PRIORITY,其他50%使用MAX_PRIORITY。如果你发布你的结果肯定会启发

  3. 修改 有意思,让我提交我的示例程序。我在OpenJDK6和线程优先级下:MIN_PRIORITY和MAX_PRIORITY似乎并不重要。高级线程的点击次数略高于低优先级线程的点击次数。

    import java.util.concurrent.atomic.AtomicLong;
    
    
    class Clicker implements Runnable {
        AtomicLong click = new AtomicLong();
        Thread t;
        private volatile boolean running = true;
    
        public Clicker (int p) {
            t  = new Thread(this);
            t.setPriority(p);
        }
    
        public void run() {
            while(running) {
                click.incrementAndGet();
                longOP();
            }
        }
    
        private void longOP() {
            outer:
            for (int i = 2; i <= 10000 && running; i++) {
                final int NUM = i;
                for (int j = 2; j * j <= NUM && running; j++) {
                    if (NUM % j == 0) {
                        continue outer;
                    }
                }
                System.out.print("[" + NUM + "],");
            }
            System.out.println();
            for (int i = -90; i <= 90 && running; i++) {
                double rad = Math.toRadians(i);
                double value = Math.sqrt(Math.abs(Math.pow(Math.PI * Math.sin(rad), 10.0))) + Math.tan(rad) * Math.cos(rad); //lol
                System.out.print("[" + i + " " + value + "],");
            }
    
        }
    
        public void stop() {
            running = false;
        }
    
        public void start() {
            t.start();
        }
    }
    
    public class Priority {
        public static void main(String args[]) {
            Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
    
            final int MAX_THREADS = 1000;
            final long MAX_RUN_TIME = 60 * 1000; //millis
    
            Clicker clickHi[] = new Clicker[MAX_THREADS];
            Clicker clickLow[] = new Clicker[MAX_THREADS];
            for (int i = 0; i < MAX_THREADS; ++i) {
                clickHi[i] = new Clicker(Thread.MAX_PRIORITY);
                clickLow[i] = new Clicker(Thread.MIN_PRIORITY); 
    
                clickHi[i].start();
                clickLow[i].start();
            }
    
    
            try {
                Thread.sleep(MAX_RUN_TIME);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                System.out.println("main thread interrupted");
            }
    
            for (int i = 0; i < MAX_THREADS; ++i) {
                clickHi[i].stop();
                clickLow[i].stop();
            }
    
            for (int i = 0; i < MAX_THREADS; ++i) {
                try {
                    clickHi[i].t.join();
                    clickLow[i].t.join();
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    System.out.println("interrupted exception catched in main");
                }
            }
    
            long totalLowClicks = 0, totalHighClicks = 0;
            for (int i = 0; i < MAX_THREADS; ++i) {
                totalLowClicks += clickLow[i].click.longValue();
                totalHighClicks += clickHi[i].click.longValue();
    
                System.out.println("low-priority thread " + clickLow[i].click);
                System.out.println("hi-priority thread " + clickHi[i].click);
            }
    
            System.out.println("Sum of LOW clicks : " + totalLowClicks);
            System.out.println("Sum of HI  clicks : " + totalHighClicks);
        }
    }
    

    以上程序是cpu密集型的。您可能会遇到内存不足错误。但只是为了好玩,发布你的结果。