> > What is the default priority of the crontab thread? Can i set the
> > priority for the thread from crontab.xml?
> When I took a look at
> http://java.sun.com/docs/books/tutorial/essential/threads/prio
> rity.html
> my conclusion was that you don't want to set thread to a lower
> priority in a server environment. My understanding is also that
> priority is handled differently on different JVM's/Os'se. I hope I was
> right since in the last year I have removed quite a lot to code that
> had to do with priority.
Java makes certain guarantees as to how its threads are scheduled. Every thread has a
priority value. If, at any time, a thread of a higher priority than the current thread
becomes runnable, it preempts the lower priority thread and begins executing. By
default, threads at the same priority are scheduled round robin, which means once a
thread starts to run, it continues until it does one of the following:
Sleeps - Calls Thread.sleep() or wait() Waits for lock - Waits for a lock in order to
run a synchronized method Blocks on I/O - Blocks, for example, in a xread() or an
accept() call Explicitly yields control - Calls yield() Terminates - Completes its
target method or is terminated by a stop() call
Mapping of Java's 10 thread priorities to the underlying OS is platform dependent. For
example, NT has 7 priorities which needs to get mapped to Java's 10 -- and you don't
really know what Java priority maps to what NT priority. NT also "priority boosts"
threads on occassion, which temporarily adjusts a thread's priority without you
actually knowing about it. You might consider not relying on anything other than
Thread.MAX_PRIORITY, Thread.MIN_PRIORITY and Thread.NORM_PRIORITY for your scheduling
needs.
Another thing, Java leaves certain aspects of scheduling up to the implementation. The
main point here is that some, but not all, implementations of Java use time slicing on
threads of the same priority. In a time-sliced system, thread processing is chopped
up, so that each thread runs for a short period of time before the context is switched
to the next thread. This implementation-dependent aspect of Java isn't a big deal,
since it doesn't hurt for an implementation to add time slicing on top of the default
round-robin scheduling. Higher priority threads still preempt lower priority threads
in this scheme.
As of Java Release 1.0, Sun's JVM for the Windows 95 and Windows NT platforms uses
time slicing. Sun's Java 1.0 for the Solaris UNIX platforms doesn't. Pre-1.2 JVMs had
a green thread model to schedule and time-slice the threads inside the JVM. A green
JVM on Solaris behaved like a Windows native JVM. Running code on both platforms
behaved completely different.
There are more things to say about Solaris and java threads. Prior to Solaris 9 the
threading model was M:N. This means that M native threads (Java threads run on native
ones) were multiplexed on top of N kernel threads (LWPs). The relationship between
native threads and LWPs was fluid and dynamic and could change even while a thread was
running and without the knowlege of the thread. Because of the relationship between
LWPs and native threads was unstable there was no reliable way to change the
dispatching priority of a native thread. The JVM could change the priority of the LWP
on which a java thread was currently running, but the thread could switch to another
LWP without the JVM's knowledge.
The default thread model in Solaris 9 and better implements a much more simple and
robust 1:1 mapping. Each native thread is assigned to a unique LWP, and that
relationship is stable for the lifetime of the native thread.
Prior to java 1.4.2 the priority had very little effect on the execution behaviour of
a java thread. The setPriority() did only set the priority of native thread (not LWP)
which is only used for user-level process-local sleep queues.
In java 1.4.2 the underlying threading model is detected and for some models the LWP
priority is set by the setPriority() method. Java 1.5 improves the 1.4.2 thread model
to let native threads compete better with other C program threads.
To conclude, Thread.setPriority() and Thread.yield() are advisory. They constitute
hints from the application to the JVM. Properly written robust platform-independent
Java code will use setPriority() and yield() to optimize the performance of the
application, but should not depend on these attributes for correctness. Be aware that
all JVMs do not implement time-slicing the same way. On some VMs, it may be necessary
to use the Thread.yield() method to enforce that no thread consumes all resources.
Nico
Some educational code which is on my system for ages.
/**
* MyThread is a thread that goes into a hard loop and prints its message.
* Since we don't specify a priority for either thread, they both inherit the priority
of
* their creator, so they have the same priority. When you run this example, you will
see
* how your Java implementation does it scheduling. Under a round-robin scheme, only
"Foo"
* should be printed; "Bar" never appears. In a time-slicing implementation, you should
* occasionally see the "Foo" and "Bar" messages alternate.
*
* Change the priority of the second thread. This changes how the example behaves. Now
you
* may see a few "Foo" messages, but "Bar" should quickly take over and not relinquish
control,
* regardless of the scheduling policy.
*/
class MyThread extends Thread {
String message;
MyThread(String message) {
this.message = message;
}
public void run() {
while (true)
System.out.print(message + " ");
}
public static void main(String[] args) {
new MyThread("Foo").start();
Thread bar = new MyThread("Bar");
// bar.setPriority( Thread.NORM_PRIORITY + 1 );
bar.start();
}
}