Customizing a Threads run Method

Customizing a Thread s run Method

The run method gives a thread something to do. Its code implements the thread's running behavior. A thread's run method can do anything that can be encoded in statements: compute a list of prime numbers, sort some data, perform some animation.

The Thread class implements a generic thread that, by default, does nothing. That is, the implementation of its run method is empty. This is not particularly useful, so there are two techniques for providing a run method for a thread:

The Runnable interface is discussed later in this chapter in the section Implementing the Runnable Interface (page 279).

Subclassing Thread and Overriding run

The first way to customize a thread is to subclass Thread (itself a Runnable object) and to override its empty run method so that it does something. Let's look at the SimpleThread class, the first of two classes in this example, which does just that:

public class SimpleThread extends Thread { public SimpleThread(String str) { super(str); } public void run() { for (int i = 0; i < 10; i++) { System.out.println(i + " " + getName()); try { sleep((int)(Math.random() * 1000)); } catch (InterruptedException e) {} } System.out.println("DONE! " + getName()); } }

The first method in the SimpleThread class is a constructor that takes a String as its only argument. This constructor is implemented by calling a superclass constructor that sets the Thread's name, which is used later in the program.

The next method in the SimpleThread class is the run method. This method, the heart of any Thread, defines what the Thread does when it's running. The run method of the SimpleThread class overrides the empty method implementation in the Thread class and contains a for loop that iterates ten times. In each iteration, the method displays the iteration number and the name of the Thread. Then the method sleeps for a random interval of up to 1 second. After the loop has finished, the run method prints DONE! and the name of the thread. That's it for the SimpleThread class. Let's put it to use in TwoThreadsDemo.

The TwoThreadsDemo class contains a main method that creates two SimpleThread threads: Jamaica and Fiji. (If you can't decide where to go on vacation, use this program to decide.)

public class TwoThreadsDemo { public static void main (String[] args) { new SimpleThread("Jamaica").start(); new SimpleThread("Fiji").start(); } }

The main method starts each thread immediately following its construction by calling the start method, which in turn calls the run method. Compile and run the program and watch your vacation fate unfold. You should see output similar to this:

Note how the output from each thread is intermingled with the output from the other. The reason is that both SimpleThread threads are running concurrently. So both run methods are running, and both threads are displaying their output at the same time. When the loop completes, the thread stops running and dies.

Now let's look at another example, the Clock applet, that uses the other technique for providing a run method to a Thread.

Implementing the Runnable Interface

The following Clock applet displays the current time and updates its display every second. If you bring up the online version of this section in an HTML browser, you can scroll the page and perform other tasks while the clock updates. The reason is that the code that updates the clock's display runs within its own thread.

http://java.sun.com/docs/books/tutorial/essential/threads/clock.html

The Clock applet uses a technique different from SimpleThread's for providing the run method for its thread. Instead of subclassing Thread, Clock implements the Runnable interface and therefore implements the run method defined in it. Clock then creates a thread with itself as the Thread's target. When created in this way, the Thread gets its run method from its target. The code that accomplishes this is shown in boldface:

import java.awt.Graphics; import java.util.*; import java.text.DateFormat; import java.applet.Applet; public class Clock extends Applet implements Runnable { private Thread clockThread = null; public void start() { if (clockThread == null) { clockThread = new Thread(this, "Clock"); clockThread.start(); } } public void run() { Thread myThread = Thread.currentThread(); while (clockThread == myThread) { repaint(); try { Thread.sleep(1000); } catch (InterruptedException e) { //the VM doesn't want us to sleep anymore, //so get back to work } } } public void paint(Graphics g) { //get the time and convert it to a date Calendar cal = Calendar.getInstance(); Date date = cal.getTime(); //format it and display it DateFormat dateFormatter = DateFormat.getTimeInstance(); g.drawString(dateFormatter.format(date), 5, 10); } //overrides Applet's stop method, not Thread's public void stop() { clockThread = null; } }

The Clock applet's run method loops until the browser asks it to stop. During each iteration of the loop, the clock repaints its display. The paint method figures out what time it is, formats it in a localized way, and displays it. You'll see more of the Clock applet in the section The Life Cycle of a Thread (page 281), which uses it to teach you about the life of a thread.

Deciding to Use the Runnable Interface

You have now seen two ways to provide the run method.

  1. Subclass the Thread class defined in the java.lang package and override the run method. See the SimpleThread class described in the section Subclassing Thread and Overriding run (page 278).
  2. Provide a class that implements the Runnable interface (also defined in the java.lang package) and therefore implements the run method. In this case, a Runnable object provides the run method to the thread. See the Clock applet in the previous section.

There are good reasons for choosing either of these options over the other. However, for most cases, including that of the Clock applet, the following rule of thumb will guide you to the better option.

Rule of Thumb

If your class must subclass another class (the most common example being Applet), you should use Runnable as described in option 2.

To run in a browser, the Clock class has to be a subclass of the Applet class. Also, the Clock applet needs a thread so that it can continuously update its display without taking over the process in which it is running. (Some browsers might create a new thread for each applet so as to prevent a misbehaved applet from taking over the main browser thread. However, you should not count on this when writing your applets; your applets should create their own threads when doing computer-intensive work.) But because the Java programming language does not support multiple-class inheritance, the Clock class cannot be a subclass of both Thread and Applet. Thus, the Clock class must use the Runnable interface to provide its threaded behavior.

Категории