> > 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();
    }
}


Reply via email to