Thread Properties


In the following sections, we discuss miscellaneous properties of threads: thread priorities, daemon threads, thread groups, and handlers for uncaught exceptions.

Thread Priorities

In the Java programming language, every thread has a priority. By default, a thread inherits the priority of its parent thread, that is, the thread that started it. You can increase or decrease the priority of any thread with the setPriority method. You can set the priority to any value between MIN_PRIORITY (defined as 1 in the THRead class) and MAX_PRIORITY (defined as 10). NORM_PRIORITY is defined as 5.

Whenever the thread-scheduler has a chance to pick a new thread, it prefers threads with higher priority. However, thread priorities are highly system dependent. When the virtual machine relies on the thread implementation of the host platform, the Java thread priorities are mapped to the priority levels of the host platform, which may have more or fewer thread priority levels.

For example, Windows NT/XP has seven priority levels. Some of the Java priorities will map to the same operating system level. In the Sun JVM for Linux, thread priorities are ignored altogetherall threads have the same priority.

Thus, it is best to treat thread priorities only as hints to the scheduler. You should never structure your programs so that their correct functioning depends on priority levels.

CAUTION

If you do use priorities, you should be aware of a common beginner's error. If you have several threads with a high priority that rarely block, the lower-priority threads may never execute. Whenever the scheduler decides to run a new thread, it will choose among the highest-priority threads first, even though that may starve the lower-priority threads completely.



 java.lang.Thread 1.0 

  • void setPriority(int newPriority)

    sets the priority of this thread. The priority must be between Thread.MIN_PRIORITY and Thread.MAX_PRIORITY. Use Thread.NORM_PRIORITY for normal priority.

  • static int MIN_PRIORITY

    is the minimum priority that a Thread can have. The minimum priority value is 1.

  • static int NORM_PRIORITY

    is the default priority of a Thread. The default priority is 5.

  • static int MAX_PRIORITY

    is the maximum priority that a THRead can have. The maximum priority value is 10.

  • static void yield()

    causes the currently executing thread to yield. If there are other runnable threads with a priority at least as high as the priority of this thread, they will be scheduled next. Note that this is a static method.

Daemon Threads

You can turn a thread into a daemon thread by calling

 t.setDaemon(true); 

There is nothing demonic about such a thread. A daemon is simply a thread that has no other role in life than to serve others. Examples are timer threads that send regular "timer ticks" to other threads. When only daemon threads remain, the virtual machine exits. There is no point in keeping the program running if all remaining threads are daemons.


 java.lang.Thread 1.0 

  • void setDaemon(boolean isDaemon)

    marks this thread as a daemon thread or a user thread. This method must be called before the thread is started.

Thread Groups

Some programs contain quite a few threads. It then becomes useful to categorize them by functionality. For example, consider an Internet browser. If many threads are trying to acquire images from a server and the user clicks on a Stop button to interrupt the loading of the current page, then it is handy to have a way of interrupting all these threads simultaneously. The Java programming language lets you construct what it calls a thread group so that you can simultaneously work with a group of threads.

You construct a thread group with the constructor:

 String groupName = . . .; ThreadGroup g = new ThreadGroup(groupName) 

The string argument of the ThreadGroup constructor identifies the group and must be unique. You then add threads to the thread group by specifying the thread group in the thread constructor.

 Thread t = new Thread(g, threadName); 

To find out whether any threads of a particular group are still runnable, use the activeCount method.

 if (g.activeCount() == 0) {    // all threads in the group g have stopped } 

To interrupt all threads in a thread group, simply call interrupt on the group object.

 g.interrupt(); // interrupt all threads in group g 

However, executors let you achieve the same task without requiring the use of thread groupssee page 63.

Thread groups can have child subgroups. By default, a newly created thread group becomes a child of the current thread group. But you can also explicitly name the parent group in the constructor (see the API notes). Methods such as activeCount and interrupt refer to all threads in their group and all child groups.


 java.lang.Thread 1.0 

  • Thread(ThreadGroup g, String name)

    creates a new Thread that belongs to a given ThreadGroup.

    Parameters:

    g

    The thread group to which the new thread belongs

     

    name

    The name of the new thread


  • ThreadGroup getThreadGroup()

    returns the thread group of this thread.


 java.lang.ThreadGroup 1.0 

  • ThreadGroup(String name)

    creates a new ThreadGroup. Its parent will be the thread group of the current thread.

    Parameters:

    name

    The name of the new thread group


  • THReadGroup(ThreadGroup parent, String name)

    creates a new ThreadGroup.

    Parameters:

    parent

    The parent thread group of the new thread group

     

    name

    The name of the new thread group


  • int activeCount()

    returns an upper bound for the number of active threads in the thread group.

  • int enumerate(Thread[] list)

    gets references to every active thread in this thread group. You can use the activeCount method to get an upper bound for the array; this method returns the number of threads put into the array. If the array is too short (presumably because more threads were spawned after the call to activeCount), then as many threads as fit are inserted.

    Parameters:

    list

    An array to be filled with the thread references


  • ThreadGroup getParent()

    gets the parent of this thread group.

  • void interrupt()

    interrupts all threads in this thread group and all of its child groups.

Handlers for Uncaught Exceptions

The run method of a thread cannot throw any checked exceptions, but it can be terminated by an unchecked exception. In that case, the thread dies.

However, there is no catch clause to which the exception can be propagated. Instead, just before the thread dies, the exception is passed to a handler for uncaught exceptions.

The handler must belong to a class that implements the THRead.UncaughtExceptionHandler interface. That interface has a single method,

 void uncaughtException(Thread t, Throwable e) 

As of JDK 5.0, you can install a handler into any thread with the setUncaughtExceptionHandler method. You can also install a default handler for all threads with the static method setDefaultUncaughtExceptionHandler of the Thread class. A replacement handler might use the logging API to send reports of uncaught exceptions into a log file.

If you don't install a default handler, the default handler is null. However, if you don't install a handler for an individual thread, the handler is the thread's THReadGroup object.

The ThreadGroup class implements the THRead.UncaughtExceptionHandler interface. Its uncaughtException method takes the following action:

  1. If the thread group has a parent, then the uncaughtException method of the parent group is called.

  2. Otherwise, if the Thread.getDefaultExceptionHandler method returns a non-null handler, it is called.

  3. Otherwise, if the Throwable is an instance of ThreadDeath, nothing happens.

  4. Otherwise, the name of the thread and the stack trace of the Throwable are printed on System.err.

That is the stack trace that you have undoubtedly seen many times in your programs.

NOTE

Prior to JDK 5.0, you could not install a handler for uncaught exceptions into each thread, nor could you specify a default handler. To install a handler, you needed to subclass the ThreadGroup class and override the uncaughtException method.



 java.lang.Thread 1.0 

  • static void setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler handler) 5.0

  • static Thread.UncaughtExceptionHandler getDefaultUncaughtExceptionHandler() 5.0

    set or get the default handler for uncaught exceptions.

  • void setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler handler) 5.0

  • THRead.UncaughtExceptionHandler getUncaughtExceptionHandler() 5.0

    set or get the handler for uncaught exceptions. If no handler is installed, the thread group object is the handler.


 java.lang.Thread.UncaughtExceptionHandler 5.0 

  • void uncaughtException(Thread t, Throwable e)

    Define this method to log a custom report when a thread is terminated with an uncaught exception.

    Parameters:

    t

    The thread that was terminated due to an uncaught exception

     

    e

    The uncaught exception object



 java.lang.ThreadGroup 1.0 

  • void uncaughtException(Thread t, Throwable e)

    calls this method of the parent thread group if there is a parent, or calls the default handler of the THRead class if there is a default handler, or otherwise prints a stack trace to the standard error stream. (However, if e is a THReadDeath object, then the stack trace is suppressed. ThreadDeath objects are generated by the deprecated stop method.)



    Core JavaT 2 Volume II - Advanced Features
    Building an On Demand Computing Environment with IBM: How to Optimize Your Current Infrastructure for Today and Tomorrow (MaxFacts Guidebook series)
    ISBN: 193164411X
    EAN: 2147483647
    Year: 2003
    Pages: 156
    Authors: Jim Hoskins

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net