I intend to use thread priorities in my Java code. The application should work on my Linux system:
>uname -a Linux <host> 3.0.0-15-generic #26-Ubuntu SMP <date> x86_64 x86_64 x86_64 GNU/Linux >java -version java version "1.6.0_23" OpenJDK Runtime Environment (IcedTea6 1.11pre) (6b23~pre11-0ubuntu1.11.10.1) OpenJDK 64-Bit Server VM (build 20.0-b11, mixed mode)
After some reading on the Internet, I run my test application with the following command:
sudo java -XX:+UseThreadPriorities -XX:ThreadPriorityPolicy=1 -jar ThreadPriorityTest.jar
The test application consists of the following two classes:
package ch.mypackage; public class CountingRunnable implements Runnable{ private long count=0; private boolean goOn=true; public long getCount() { return count; } public void stop(){ goOn=false; } public void run() { for(long iteration=0;goOn&&iteration<Long.MAX_VALUE;++iteration){ ++count; } } } package ch.mypackage; public class PriorizedCountingThreads { private static final int NUM_MILLIS_TO_COUNT_FOR = 1*60*1000; private static CountingRunnable[] runnables; private static Thread[] threads; public static void main(String[] args) { Thread.currentThread().setPriority(Thread.MAX_PRIORITY); System.out.println("MIN_PRIORITY: "+Thread.MIN_PRIORITY); System.out.println("MAX_PRIORITY: "+Thread.MAX_PRIORITY); int numPriorityLevels=(Thread.MAX_PRIORITY-Thread.MIN_PRIORITY)+1; init(numPriorityLevels); startThreads(); try { Thread.sleep(NUM_MILLIS_TO_COUNT_FOR); } catch (InterruptedException e) { e.printStackTrace(); } stopRunnables(); printCounts(); } private static void printCounts() { for(int i=0;i<runnables.length;++i){ System.out.println(threads[i].getName()+" has priority: "+threads[i].getPriority()+" and count:"+runnables[i].getCount()); } } private static void stopRunnables() { for(int i=0;i<runnables.length;++i){ runnables[i].stop(); } } private static void startThreads() { for(int i=0;i<threads.length;++i){ threads[i].start(); } } private static void init(int numPriorityLevels) { runnables=new CountingRunnable[numPriorityLevels]; threads=new Thread[runnables.length]; for(int i=0;i<runnables.length;++i){ int priority=i+1; runnables[i]=new CountingRunnable(); threads[i]=new Thread(runnables[i]); threads[i].setPriority(priority); threads[i].setName("PriorityThread_"+priority); } } }
If I run the program within one minute (NUM_MILLIS_TO_COUNT_FOR = 1 * 60 * 1000), I get the following output:
MIN_PRIORITY: 1 MAX_PRIORITY: 10 PriorityThread_1 has priority: 1 and count:12658044343 PriorityThread_2 has priority: 2 and count:19008431582 PriorityThread_3 has priority: 3 and count:30618946099 PriorityThread_4 has priority: 4 and count:34408365142 PriorityThread_5 has priority: 5 and count:36694025023 PriorityThread_6 has priority: 6 and count:40493710165 PriorityThread_7 has priority: 7 and count:42826305342 PriorityThread_8 has priority: 8 and count:42203891414 PriorityThread_9 has priority: 9 and count:43128747383 PriorityThread_10 has priority: 10 and count:43416371500
According to this result, priorities seem to have the expected impact! But if I dump the stream with "jstack" or "kill -s QUIT", then I get the following output, which implies that EVERY THREAD HAS A VERY PRIORITY (prio = 10):
"PriorityThread_10" prio=10 tid=0x00007ff7e406f800 nid=0x12e6 runnable [0x00007ff7e2562000] java.lang.Thread.State: RUNNABLE at ch.mypackage.CountingRunnable.run(CountingRunnable.java:17) at java.lang.Thread.run(Thread.java:679) "PriorityThread_9" prio=10 tid=0x00007ff7e406d800 nid=0x12e5 runnable [0x00007ff7e2663000] java.lang.Thread.State: RUNNABLE at ch.mypackage.CountingRunnable.run(CountingRunnable.java:17) at java.lang.Thread.run(Thread.java:679) "PriorityThread_8" prio=10 tid=0x00007ff7e406b000 nid=0x12e4 runnable [0x00007ff7e2764000] java.lang.Thread.State: RUNNABLE at ch.mypackage.CountingRunnable.run(CountingRunnable.java:17) at java.lang.Thread.run(Thread.java:679) "PriorityThread_7" prio=10 tid=0x00007ff7e4069000 nid=0x12e3 runnable [0x00007ff7e2865000] java.lang.Thread.State: RUNNABLE at ch.mypackage.CountingRunnable.run(CountingRunnable.java:17) at java.lang.Thread.run(Thread.java:679) "PriorityThread_6" prio=10 tid=0x00007ff7e4067000 nid=0x12e2 runnable [0x00007ff7e2966000] java.lang.Thread.State: RUNNABLE at ch.mypackage.CountingRunnable.run(CountingRunnable.java:17) at java.lang.Thread.run(Thread.java:679) "PriorityThread_5" prio=10 tid=0x00007ff7e4065000 nid=0x12e1 runnable [0x00007ff7e2a67000] java.lang.Thread.State: RUNNABLE at ch.mypackage.CountingRunnable.run(CountingRunnable.java:17) at java.lang.Thread.run(Thread.java:679) "PriorityThread_4" prio=10 tid=0x00007ff7e4063000 nid=0x12e0 runnable [0x00007ff7e2b68000] java.lang.Thread.State: RUNNABLE at ch.mypackage.CountingRunnable.run(CountingRunnable.java:17) at java.lang.Thread.run(Thread.java:679) "PriorityThread_3" prio=10 tid=0x00007ff7e4061000 nid=0x12df runnable [0x00007ff7e2c69000] java.lang.Thread.State: RUNNABLE at ch.mypackage.CountingRunnable.run(CountingRunnable.java:17) at java.lang.Thread.run(Thread.java:679) "PriorityThread_2" prio=10 tid=0x00007ff7e405d000 nid=0x12de runnable [0x00007ff7e2d6a000] java.lang.Thread.State: RUNNABLE at ch.mypackage.CountingRunnable.run(CountingRunnable.java:17) at java.lang.Thread.run(Thread.java:679) "PriorityThread_1" prio=10 tid=0x00007ff7e4049800 nid=0x12dd runnable [0x00007ff7e2e6b000] java.lang.Thread.State: RUNNABLE at ch.mypackage.CountingRunnable.run(CountingRunnable.java:17) at java.lang.Thread.run(Thread.java:679)
If I do the same on a Windows machine, the prio values โโare correct, according to the priority mappings I found here .
So, is this a bug in jstack, or am I doing something wrong?
If I execute "top | grep java", I get the following:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 3394 root 20 0 4444m 15m 8376 S 789 0.1 0:47.52 java
which implies that the main thread has a priority of 20, while "top -H | grep java" leads to the following output:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 3457 root 15 -5 4444m 15m 8384 R 99 0.1 0:08.60 java 3456 root 16 -4 4444m 15m 8384 R 97 0.1 0:08.41 java 3455 root 17 -3 4444m 15m 8384 R 93 0.1 0:08.42 java 3454 root 18 -2 4444m 15m 8384 R 97 0.1 0:08.27 java 3453 root 19 -1 4444m 15m 8384 R 97 0.1 0:07.50 java 3452 root 20 0 4444m 15m 8384 R 51 0.1 0:07.44 java 3451 root 21 1 4444m 15m 8384 R 35 0.1 0:04.83 java 3450 root 22 2 4444m 15m 8384 R 99 0.1 0:04.78 java 3449 root 23 3 4444m 15m 8384 R 95 0.1 0:07.47 java 3448 root 24 4 4444m 15m 8384 R 18 0.1 0:02.85 java
which shows that java thread priorities really affect OS thread priorities.
But where does jstack have a value of 10 in prio = 10 of? Is this just an arbitrary value?