views:

1230

answers:

4

How are the java API thread priorities (1-10) gets translated to the OS level priorities since most OS don't have thread priority levels (in terms of number) which match this.

So keeping in mind , can there be a scenario when two or more threads with different priorities eventually get the same priority at OS level.

Please clarify, if I there is some correction in my understanding.

A: 

Since we're talking about threads, I think that this never reaches the OS directly. The priority is probably a hint to the JRE on how to schedule CPU time each thread. To deal with your example, there needs to be some sort of 'tie-breaking' algorithm.

Basically, this is going to be on-top of OS process priority unless the JRE is using 3rd party threading standards like POSIX instead of implementing everything internally.

Dana the Sane
+7  A: 

Indeed, some priority levels can map to the same "native" priority level. Here's the list (based on the Hotspot code in OpenJDK 6):

Solaris

  • 1 ⇒ 0
  • 2 ⇒ 32
  • 3 ⇒ 64
  • 4 ⇒ 96
  • 5 – 10 ⇒ 127

Of note is that on Solaris, you can't raise the thread priority above normal, only lower it: the priority value for 5 is the same as any of the higher values.

Linux

  • 1 – 10 ⇒ 4 – -5 (nice values)

Of note is that on Linux, different thread priorities in Java do map to distinct priority values at native level.

Windows

  • 1 – 2 ⇒ THREAD_PRIORITY_LOWEST
  • 3 – 4 ⇒ THREAD_PRIORITY_BELOW_NORMAL
  • 5 – 6 ⇒ THREAD_PRIORITY_NORMAL
  • 7 – 8 ⇒ THREAD_PRIORITY_ABOVE_NORMAL
  • 9 – 10 ⇒ THREAD_PRIORITY_HIGHEST
Chris Jester-Young
Do you have a reference handy for this and is this a direct mapping or an emulation based on how the OS's treat these values?
Dana the Sane
Not officially documented, but read hotspot/src/os/{linux,solaris,win32}/vm/os_{linux,solaris,win32}.cpp in the OpenJDK source (search for java_to_os_priority) for the values. :-)
Chris Jester-Young
+1  A: 

Your understanding is correct - Java thread priorities do not map cleanly to OS thread priorities.

As a result, if your algorithm relies in any way on the details of thread priority mapping, then it is broken, since it will vary according to so many variables. Upgrading your JRE or applying a patch/service pack to your OS could break it, for example - and of course just running on a different OS will have consequences too.

Except in very unusual cases, using only two priorities will be sufficient - Normal and Low. Most work will be done in a Normal thread. Low priority should be reserved for threads that must not be allowed to starve the threads of Normal priority, instead just gobbling up and processor power not otherwise used.

While you can get more fine-grained than this if you choose, you need to be aware that any greater detail will likely be lost on the target platform.

Bill Michell
+1  A: 

I'm not so sure on Sun JVM on Linux. Wrote a quick Java proggy to spawn 10 threads with each priority and calculate pi (4*atan(1) method) with BigDecimals 500,000 times each, join on each thread and report the elapsed time for run method. Yeah, prob'ly not the best example, but keeping it basic.

$uname -r && grep bogomips /proc/cpuinfo
2.4.33.3
bogomips        : 4312.26
$java -version 2>&1 |head -1
Java version "1.6.0_01"
$javac T.java && java -Xmx32m T
1:3112
2:2636
3:2662
4:3118
5:2870
6:3319
7:3412
8:3304
9:3299
10:3069

Looks like not much of a deviation that one would expect! That was on a small virtual Linux machine. Let's try it on a real slab just in case, this box is fairly active too with load averages rarely below 7, let's just see how we schedule in an environment like this:

$uname -r && grep bogomips /proc/cpuinfo
2.6.9-67.ELsmp
bogomips        : 3992.93
bogomips        : 3990.00
$java -version 2>&1 |head -1
java version "1.4.2_14"
$javac T.java && java -Xmx32m T
1:63200
2:64388
3:62532
4:58529
5:62292
6:64872
7:64885
8:64584
9:61653
10:61575

Hmmm, not much of a variation here, don't know if 1.4 even mapped threads over. Let's try a windows box. I know that Windows has a fairly aggressive thread priority schema. Anything above normal anecdotaly consumes much more. As such, let's bump up to 900,000 iterations in each thread:

C:\>java -version
java version "1.6.0_11"
C:\>java -Xmx32m T
1:12578
2:12625
3:11469
4:11453
5:10781
6:8937
7:10516
8:8406
9:9953
10:7391

Very much what we're looking for, no?

Xepoch