Controlling Threads with the Thread Class

   

Java™ 2 Primer Plus
By Steven Haines, Steve Potts

Table of Contents
Chapter 18.  Programming with Threads


You are already running at least one thread any time you are running a Java program. The main() method creates a thread to run your program in. In fact, you can call methods on this thread very easily. Listing 18.1 shows how to put a program to sleep for six seconds.

Listing 18.1 The TestSleep.java File
 /*   * TestSleep.java   *   * Created on September 25, 2002, 11:10 AM   */  package ch18;  /**   *   * @author  Stephen Potts   */  public class TestSleep  {      /** Creates a new instance of TestSleep */      public TestSleep()      {      }      public static void main(String[] args)      {          try          {          for (int i=0; i<5;i++)          {              System.out.println("The counter = " + i);              Thread.sleep(2000);          }          }catch (InterruptedException ie)          {              System.out.println("Sleep interrupted");          }          Thread t = Thread.currentThread();          System.out.println("The Thread name is " + t.getName());      }  } 

The fact that we never explicitly created a thread in this example doesn't mean that there isn't one. The main thread is created every time you run a class containing a main() method.

Any time you want to refer to the thread that is executing, you can use the static methods of the Thread class. We see one of the methods of this class called sleep().

 Thread.sleep(2000); 

The parameter, 2000, means that we want the sleep to last for 2000 miliseconds, or 2 seconds.

We need to first obtain an instance of the Thread class in a variable. This enables us to call the currentThread() method to obtain a handle to the Java object associated with the running thread.

 Thread t = Thread.currentThread(); 

We can then execute the getName() method using that handle and print it.

 System.out.println("The Thread name is " + t.getName()); 

The result of running this program is shown here. The counter statements will appear slowly, followed by the name of the thread.

 The counter = 0  The counter = 1  The counter = 2  The counter = 3  The counter = 4  The Thread name is main 

Creating Multithreaded Applications

Conceptually, the simplest way to create a program that is multithreaded is to extend the java.lang.Thread class. This prepares your program for a new thread to be created. The main() method creates the first, but you create and exercise considerable control over the new thread.

The thread class allows for the overriding of a method called run(). The run() method enables the programmer to place code in the program that will be run in parallel with the code in the main() method. This code will only be run if the start() method is invoked using a handle to the class. Listing 18.2 shows an example that runs one thread in addition to the main thread.

Listing 18.2 The TestTwoThreads1.java File
 /*   * TestTwoThreads1.java   *   * Created on September 25, 2002, 12:08 PM   */  package ch18;  /**   *    * @author  Stephen Potts   */  public class TestTwoThreads1 extends Thread  {      /** Creates a new instance of TestTwoThreads1 */      public TestTwoThreads1()      {      }      public void run()      {          for ( int i=0; i<10; i++)          {              System.out.println("Hello from the new thread");          }          Thread t = Thread.currentThread();          System.out.println("The Thread name is " + t.getName());      }      public static void main(String[] args)      {          TestTwoThreads1 ttt1 = new TestTwoThreads1();          ttt1.start();          for (int i=1; i<10; i++)          {              System.out.println("Hello from the main thread");          }      }  } 

The first thing that we do is extend the Thread class.

 public class TestTwoThreads1 extends Thread 

The next thing is to override the run() methods so that the second thread will have some observable behavior.

 public void run()  {      for ( int i=0; i<10; i++)      {          System.out.println("Hello from the new thread");      } 

We also want to see what the JVM named this thread.

 Thread t = Thread.currentThread();  System.out.println("The Thread name is " + t.getName()); 

In the main class, we instantiate an instance of this class and obtain a handle to it.

 TestTwoThreads1 ttt1 = new TestTwoThreads1(); 

We use that handle to start() the thread. Notice that we don't call run() directly. The start() method creates the new thread first, calls the run() method to run in this new thread.

 ttt1.start(); 

The result of running this example is shown here. Notice how the main thread had the CPU to itself. Later, it relinquished the CPU to the new thread, which kept control of it until it completed its processing and printed its name. Following that, the main thread got the CPU back and finished its run.

 Hello from the main thread  Hello from the main thread  Hello from the main thread  Hello from the new thread  Hello from the new thread  Hello from the new thread  Hello from the new thread  Hello from the new thread  Hello from the new thread  Hello from the new thread  Hello from the new thread  Hello from the new thread  Hello from the new thread  The Thread name is Thread-1  Hello from the main thread  Hello from the main thread  Hello from the main thread  Hello from the main thread  Hello from the main thread  Hello from the main thread 

Notice that we never explicitly ended the life of the second thread. We simply allowed the thread to reach the end of the run() method. After the JVM noticed that the run() method had completed, it destroyed the thread itself. The order of execution of the different threads can be different every time you run the program. Experiment by running this example several times and observing this behavior for yourself.

Caution

graphics/01icon17.gif

The timing of multithreaded applications is, by default and design, unpredictable. You should never depend on the timing of events in two different threads for program correctness.


The order of execution of the different threads can be different every time you run the program. Experiment by running this example several times and observing this behavior for yourself.

Setting the Names of Threads

We can also use the Thread class to assign our own name to a thread so that it will be easier to trace the behavior of the threads. Listing 18.3 shows us how this is done.

Listing 18.3 The TestThreadSetName.java File
 /*   * TestThreadSetName.java   *   * Created on September 25, 2002, 12:08 PM   */  package ch18;  /**   *   * @author  Stephen Potts   */  public class TestThreadSetName extends Thread  {      /** Creates a new instance of TestThreadSetName */      public TestThreadSetName()      {      }      public void run()      {          for ( int i=0; i<5; i++)          {              printMyName();          }      }      public void printMyName()      {          Thread t = Thread.currentThread();          System.out.println("The Thread name is " + t.getName());      }      public static void main(String[] args)      {          TestThreadSetName ttsn = new TestThreadSetName();          ttsn.setName("Created One");          ttsn.start();          Thread t2 = currentThread();          t2.setName("Main One");          for (int i=0; i<5; i++)          {              ttsn.printMyName();          }      }  } 

We create a method that can be called by either the new thread or the main thread via a handle. This method queries the executing thread to find out what its name is and prints it.

 public void printMyName()  {      Thread t = Thread.currentThread();      System.out.println("The Thread name is " + t.getName());  } 

We set the name of the new thread right after we instantiate it, but before we start() it.

 TestThreadSetName ttsn = new TestThreadSetName();  ttsn.setName("Created One");  ttsn.start(); 

The main thread's name is set by obtaining a handle and assigning a name to it.

 Thread t2 = currentThread();  t2.setName("Main One"); 

The result of running this program is shown here.

 The Thread name is Main One  The Thread name is Main One  The Thread name is Main One  The Thread name is Main One  The Thread name is Main One  The Thread name is Created One  The Thread name is Created One  The Thread name is Created One  The Thread name is Created One  The Thread name is Created One 

Meaningful names are critical when debugging a program that contains a lot of threads. The names that you assign can be something like "Video Thread," or "Sound Thread" instead of "Thread-1," or "Thread-2."


       
    Top
     



    Java 2 Primer Plus
    Java 2 Primer Plus
    ISBN: 0672324156
    EAN: 2147483647
    Year: 2001
    Pages: 332

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