Untangling Java concurrency

Java 101: Understanding Java threads, Part 1: Introducing threads and runnables

Learn how to improve Java application performance using Java threads

1 2 3 Page 3
Page 3 of 3
// RunnableDemo.java

public class RunnableDemo extends java.applet.Applet implements Runnable
{
   private Thread t;

   public void run ()
   {
      while (t == Thread.currentThread ())
      {
           int width = rnd (30);
           if (width < 2)
               width += 2;

           int height = rnd (10);
           if (height < 2)
               height += 2;

           draw (width, height);
      }
   }

   public void start ()
   {
      if (t == null)
      {
         t = new Thread (this);
         t.start ();
      }
   }

   public void stop ()
   {
      if (t != null)
         t = null;
   }

   private void draw (int width, int height)
   {
      for (int c = 0; c < width; c++)
           System.out.print ('*');

      System.out.print ('\n');

      for (int r = 0; r < height - 2; r++)
      {
           System.out.print ('*');

           for (int c = 0; c < width - 2; c++)
                System.out.print (' ');

           System.out.print ('*');

           System.out.print ('\n');
      }

      for (int c = 0; c < width; c++)
           System.out.print ('*');

      System.out.print ('\n');
   }

   private int rnd (int limit)
   {
      // Return a random number x in the range 0 <= x < limit.

      return (int) (Math.random () * limit);
   }
}

RunnableDemo describes an applet for repeatedly outputting asterisk-based rectangle outlines on the standard output. To accomplish this task, Runnable must extend the java.applet.Applet class (java.applet identifies the package in which Applet is located -- I discuss packages in a future article) and implement the Runnable interface.

An applet provides a public void start() method, which is called (typically by a Web browser) when an applet is to start running, and provides a public void stop() method, which is called when an applet is to stop running.

The start() method is the perfect place to create and start a thread, and RunnableDemo accomplishes this task by executing t = new Thread (this); t.start ();. I pass this to Thread's constructor because the applet is a runnable due to RunnableDemo implementing Runnable.

The stop() method is the perfect place to stop a thread, by assigning null to the Thread variable. I cannot use Thread's public void stop() method for this task because this method has been deprecated -- it's unsafe to use.

The run() method contains an infinite loop that runs for as long as Thread.currentThread() returns the same Thread reference as located in Thread variable t. The reference in this variable is nullified when the applet's stop() method is called.

Because RunnableDemo's new output would prove too lengthy to include with this article, I suggest you compile and run that program yourself.

You will need to use the appletviewer tool and an HTML file to run the applet. Listing 9 presents a suitable HTML file -- the width and height are set to 0 because no graphical output is generated.

Listing 9. RunnableDemo.html

 <applet code="RunnableDemo" width="0" height="0"></applet>

Specify appletviewer RunnableDemo.html to run this applet.

Thread vs Runnable?

When you face a situation where a class can either extend Thread or implement Runnable, which approach do you choose? If the class already extends another class, you must implement Runnable. However, if that class extends no other class, think about the class name. That name will suggest that the class's objects are either active or passive. For example, the name Ticker suggests that its objects are active—they tick. Thus, the Ticker class would extend Thread, and Ticker objects would be specialized Thread objects.

Review

Users expect programs to achieve strong performance. One way to accomplish that task is to use threads. A thread is an independent path of execution through program code. Threads benefit GUI-based programs because they allow those programs to remain responsive to users while performing other tasks. In addition, threaded programs typically finish faster than their nonthreaded counterparts. This is especially true of threads running on a multiprocessor machine, where each thread has its own processor. The Thread and Thread subclass objects describe threads and associate with those entities. For those classes that cannot extend Thread, you must create a runnable to take advantage of multithreading.

Next month, I continue this series by showing you how to synchronize access to shared data.

Jeff Friesen has been involved with computers for the past 20 years. He holds a degree in computer science and has worked with many computer languages. Jeff has also taught introductory Java programming at the college level. In addition to writing for JavaWorld, he has written his own Java book for beginners— Java 2 by Example, Second Edition (Que Publishing, 2001; ISBN: 0789725932)—and helped write Using Java 2 Platform, Special Edition (Que Publishing, 2001; ISBN: 0789724685). Jeff goes by the nickname Java Jeff (or JavaJeff). To see what he's working on, check out his Website at http://www.javajeff.com.

Learn more about this topic

  • Learn more about Java: See the complete listing for Jeff Friesen's Java 101 series -- archived on JavaWorld.
  • Also see the Java Tips series: More than five years of compiled tips from JavaWorld's expert readers.

1 2 3 Page 3
Page 3 of 3