Mailing Lists: Apple Mailing Lists

Image of Mac OS face in stamp
 
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Beware of worker threads



Hi all,

For those who don't subscribe to the Java Tech Tips newsletter, I'm passing this along.  It talks about a pitfall to the otherwise good practice of pushing busy work off the AWT thread.

----------

Create Threads for Long Tasks From the Event Dispatch Thread 

Here's the situation: you want to spin off a thread from the event queue to do a long task. If your event handler needs to do a long task, you don't want to block the event thread. So you create a new thread for the long task, and call invokeLater() when the task is done to handle the results on the event thread. Here's the typical usage pattern:
   public void actionPerformed(ActionEvent e) {
     Runnable longTask = new Runnable() {
       public void run() {
         // Run task to do long stuff
         ... // long task
         // Update Swing component when done
         Runnable awtTask = new Runnable() {
           public void run() {
             // Update Swing component
           }
         }
        EventQueue.invokeLater(awtTask);
       }
     };
     Thread t = new Thread(longTask);
     t.start();
   }
This is a common pattern: run long tasks off the event dispatch thread, then update the Swing component after the long task is done. It seems like the right thing to do, but it isn't. 

If you follow this pattern, you'll run across a problem that could cause your program to behave badly. When a new thread is created, it retains the thread priority of the creating thread. Because the event thread typically runs at a higher level than normal threads, threads created from the event thread inherit the higher priority. 

Here is a simple program, Threads, that demonstrates the thread priorities:
   import java.awt.*;

   public class Threads {
     public static void main(String args[]) {
       System.out.println("Main Thread priority: " +
         Thread.currentThread().getPriority());
       Runnable runner = new Runnable() {
         public void run() {
           System.out.println("Event Thread priority: " +
             Thread.currentThread().getPriority());
         }
       };
       EventQueue.invokeLater(runner);
     }
   }
If you run Threads, you'll see that the main thread has a priority of 5, and the event thread runs at a priority 6.
>> java Threads

 

  Main Thread priority: 5
  Event Thread priority: 6
The higher priority for the event thread is desirable. You want your user interfaces to be responsive. But, you don't want to extend that higher priority to non-event processing tasks. So be sure to lower the priority of user-created threads initialized from the event dispatch thread. This means: 

Change:
    Thread t = new Thread(longTask);
    t.start();
To:
    Thread t = new Thread(longTask);
    t.setPriority(Thread.NORM_PRIORITY);
    t.start();
Threads created with this new priority will not compete for processing time with the event dispatch thread. If there is something to run on the event dispatch thread, it will win -- not the worker thread. You might consider creating a WorkerThread class for just this purpose. That way you won't have to keep calling setPriority() for all new threads created from the event dispatch thread, or use a thread pool through the following new classes in the java.util.concurrent package:
  • Executors.newCachedThreadPool()
    For a thread pool with unbound size
  • Executors.newFixedThreadPool(int size)
    For a thread pool of fixed size > 1
  • Executors.newSingleThreadExecutor()
    For a thread pool of fixed size = 1
Executor was added to the standard libraries with JDK 5.0. 


----------------------------------------------

Matt Drance

DTS Engineer

Java - Dashboard - Address Book

email@hidden



 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Java-dev mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/java-dev/email@hidden

This email sent to email@hidden



Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Contact Apple | Terms of Use | Privacy Policy

Copyright © 2007 Apple Inc. All rights reserved.