0

我正在阅读来自Java The complete Reference - Herbert Schildt (TATA McGRAW HILL). 在这个示例表单中,具有较低优先级的线程应该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

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

4

2 回答 2

2

我怀疑示例图将在某种程度上取决于您的平台和作者的平台(示例是否在单核上运行?)。JVM 线程优先级是特定于操作系统/平台的。从这个有趣的文件

Linux 优先事项

在 Linux 下,您必须经过更多的努力才能使线程优先级完全发挥作用,尽管最终它们可能比在 Windows 下更有用。在 Linux 中:

  • 线程优先级仅从 Java 6 开始有效;
  • 为了让它们工作,您必须以 root 身份运行(或通过 setuid 使用 root 权限);
  • 必须包含 JVM 参数 -XX:UseThreadPriorities

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

于 2013-07-12T17:15:23.647 回答
0

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

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

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

编辑 有趣,让我提交我的示例程序。我在 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 密集型的。您可能会遇到内存不足错误。但只是为了好玩,发布你的结果。

于 2013-07-12T18:00:54.423 回答