Home : Course Map : Chapter 8 : Java :
Introduction to Threads
JavaTech
Course Map
Chapter 8

Introduction
Threads Overview
  Demo 1   Demo 2
Stopping Threads
Multi-Processing
Thread Tasks
Animations
 
 Demo 3   Demo 4  
  Demo 5

Non-interacting
  Demo 6

Task Splitting
  Demo 7

Exclusivity
  Demo 8

Communicating
  Demo 9

Priority/Scheduling
More Thread

Exercises

    Supplements
Java2D Animation
  Demo 1 
Processor View
More Concurrency
Cloning
  Demo 2  Demo 3 

     About JavaTech
     Codes List
     Exercises
     Feedback
     References
     Resources
     Tips
     Topic Index
     Course Guide
     What's New

Threads are lightweight processes spun off from the main process. We are all familiar with operating systems running separate programs in parallel, or appearing that way, at least, on a single processor system. These programs would be heavyweight processes since they run in the local machine system. Threads are similar except that they are parallel processes running inside of a program.

So in Java you can create one or more threads within your program just as you can run one or more programs in an operating system. Most JVMs, in fact, take great advantage of threads.

In Java you create threads in two ways:

  1. A class extends the Thread class and overrides it's run() method.

  2. A class implements the Runnable interface, which has one  method: run(). The class passes a reference to itself when it creates a thread. The thread then calls back to the  run() method in the class.

Here we discuss the two techniques:

Technque 1: Thread Subclass

Creating a thread subclass offers the most conceptually straightforward approach. The run() method in the thread corresponds to the main() method for an application. When the thread starts, it invokes the method run() and when the process returns from the run() method, the thread dies.

Note: You cannot resurrect a dead thread. You must instead create a new thread instance.

So in this approach the subclass must override the run() method where you put the code you wish to process in parallel to the main program.

The Thread subclass MyThread overrides run(), which has a loop that prints every 100 milliseconds for two seconds (see Java Console for output):

public class MyThread extends Thread {
  public void run () {
    int count = 0;

    while (true) {

       System.out.println ("Thread 1 alive");

       // Print every 0.10sec for 2 seconds
       try {
           Thread.sleep (100);
       } catch (InterruptedException e) {}

       count++;
       if (count >= 20) break;
    }

    System.out.println ("Thread stopping");
  } // run
} // class MyThread
MyClass1.java - an application that runs MyThread.


The start() method of MyApplet class creates an instance of MyThread and invokes the thread's start() method. (Remember to differentiate between the start() method in the Applet class, called whenever the browser page opens, and the start() in the Thread class that initiates a thread.) This will in turn invoke the run() method, which the subclass has overridden.

/** Demo of threading with a Thread subclass. **/
public class MyApplet extends java.applet.Applet {

  /** Applet's start method creates and starts a thread.**/
  public void start () {

    // Create an instance of MyThread.
    MyThread myThread = new MyThread ();

    // Start the thread
    myThread.start ();
  }
 
  public void paint(java.awt.Graphics g) {
    g.drawString("Thread Demo 1",20,20);
  }
} // class MyApplet
MyClass2.java - an application that implements Runnable.

 

The following diagram shows symbolically how the main and thread processes run in parallel.

After the MyThread is started, it will run in parallel with the original MyApplet thread. By "run", we mean that the thread process executest the run() method until that method finishes and returns.

Technique 2: Runnable Implementation

The second method is somewhat less straightforward but is often convenient for cases where you want to create a single type of thread, such as an animation in an applet.

In this case, you implement the Runnable interface and override its run() method. You pass a reference to an instance of that Runnable implementation to a thread instance and the thread calls back to the run() method in the Runnable object. The thread dies as in the previous method when the process returns from run().

The program MyRunnableApplet illustrates this approach. This class implements the Runnable interface and its run() method matches to that in the MyThread class above.. Its constructor creates an instance of the Thread class and passes a reference to itself (with the this reference) in the thread's constructor. When the start() method for the thread is invoked, the run() in MyRunnableApplet will be invoked. (See Java Console for output)

/** Demo threading with Runnable implementation.**/
public class MyRunnableApplet extends java.applet.Applet
                              implements Runnable {

  /** Applet's start method creates a thread and
    * lets it run for 2 secs. **/
  public void start () {

    // Create an instance of Thread with a
    // reference to this Runnable instance.
    Thread thread = new Thread (this);

    // Start the thread
    thread.start ();

  } // start

  /** Override the Runnable run() method. **/
  public void run() {
     int count = 0;

     while (true) {
        System.out.println ("Thread 2 alive");
        // Print every 0.10sec for 5 seconds
        try{
           Thread.sleep(100);
       } catch (InterruptedException e) {}
       count++;
       if ( count >= 20 ) break;
     }
     System.out.println ("Thread stopping");
  } // run

  public void paint(java.awt.Graphics g) {
    g.drawString("Thread demo 2", 20, 20);
  }

} // class MyRunnableApplet

The following diagram shows schematically how this approach works:

You see that the primary difference is that the thread invokes the run() method in the Runnable object rather that invoking its own run() method.

Subclass vs. Runnable

So why two thread creation techniques? The choice between the two methods depends on the particular application and what seems most appropriate and convenient.

The Runnable technique is particularly convenient when you want to create just a single thread to carry out a specific task. The run() method will have access to the instance variables in the Runnable object. For example, a common approach to applet animation is to make the applet Runnable. The run() method then has access to the applet's variables, which could be parameters passed in the applet tags or set by the user via the graphical interface.

Note also that since there are no restrictions on the number of interfaces that a class can implement, it is easy to add Runnable to a class.

On the other hand, if you want to create multiple threads, then it usually makes more sense to use a Thread subclass. This helps to better conceptualize the threads as independent objects, each with its own independent sets of variables (as opposed to sharing variables in the Runnable object.) You can set the values of whatever parameters they need via their constructors or "setter" methods.

References & Web Resources

 

Last update: Nov. 5, 2004

              Tech
Timers
  Demo 1
Hist. Adapt Range
  Demo 2
Sorting in Java
  Demo 3
Histogram Median
  Demo 4
Refactoring
  Demo 5
Error Bars
  Demo 6
Exercises

           Physics
Least Squares Fit
  Demo 1
Fit to Polynomial
  Demo 2
Fit Hist Errors
  Demo 3
Discretization
  Demo 4
Timing
  Demo 5
Exercises

  Part I Part II Part III
Java Core 1  2  3  4  5  6  7  8  9  10  11  12 13 14 15 16 17
18 19 20
21
22 23 24
Supplements

1  2  3  4  5  6  7  8  9  10  11  12

Tech 1  2  3  4  5  6  7  8  9  10  11  12
Physics 1  2  3  4  5  6  7  8  9  10  11  12

Java is a trademark of Sun Microsystems, Inc.