Java Threads

Dr. Ramesh Yerraballi
A brief tutorial on programming Threads in Java
There are at least three ways to create threads in Java.
  1. The right way (implement the Runnable Interface)
  2. The easy but not necessarily best way (extend the Thread Class)
  3. The lazy and inflexible "dont-care" way  (Adapter using annonymous class)
In all the example code I am assuming that we need a thread that executes some functionality captured by the routine "Work()". That is, you want to create a thread that executes this functionality while the program that created this thread continues to do other stuff. The functionaility provided by Work() in the examples is trivial involving just printing the string "+|+" repeatedly.
To run any of the following examples copy them into the appropriate file (first to a file XApp.java, the second to a file YApp.java and the third to AApp.java). When you compile and run these you should see the worker and the main program take turns printing a few of their respective lines.
1. IMPLEMENTING RUNNABLE
import java.io.*;
import java.lang.Thread;

public class XApp {
               public static void main( String arrgs[] ) {
                   X worker = new X(); // We create a worker thread to dance continously
                   DoOtherStuff(); // Let the main thread do other stuff
               }
               public static void DoOtherStuff() {
                         while(true)
                                System.out.println("-|-");
               }
}
class X implements Runnable {
               X() {
                   Thread t = new Thread(this);
                   t.start();
               }
               public void run() {
                   Work();  //some code that executes the functionality of the thread
               }
               public void Work() {
                   while(true)
                            System.out.println("+|+");
               }
 }

Since java allows a class to implement multiple interfaces the Class X  could implement other interfaces too. Also the reason we call this the  right way is because the class X is really wanting to add the  functionality of "runnability" to itself and not necessarily extend the  functionality of a thread as the next option (2) implies. This is a inheritance nuance that you would appreciate if you understood the true purpose of inheritance.

 2. EXTENDING A THREAD

import java.io.*;
import java.lang.Thread;
public class YApp {
               public static void main( String arrgs[] ) {
                   Y worker = new Y(); // We create a worker thread to dance continously
                   DoOtherStuff(); // Let the main thread do other stuff
               }
               public static void DoOtherStuff() {
                         while(true)
                                System.out.println("-|-");
               }
}
// Here is the Thread defined as a separate class
class Y extends Thread {
               Y() {
                   start();
               }
               public void run() {
                   Work();  //some code that executes the functionality of the thread
               }
               public void Work() {
                   while(true)
                            System.out.println("+|+");
               }
}


 3. ADAPTER Technique

public class AApp {
     public static void main( String args[] ) {
               Thread t = new Thread (new Runnable() {
                                                 public void run() {
                                                      Work();
                                                 }
                                             }
                                      );
               t.start();
               DoOtherStuff(); // Let the main thread do other stuff
            }
     public static void Work() {
               while(true)
                  System.out.println("+|+");
     }
     public static void DoOtherStuff() {
               while(true)
                      System.out.println("-|-");
     }
   }
 You are thinking the last method is the easiest! you are right but it is also the least flexible. Given that you have an anonymous class (defined by the code between "(new Runnable..." till the second "}" on a line by itself) you cannot interact with it anymore. In the earlier two methods for creating the thread you could interact with the thread from the main thread simply by using  the reference worker, that you have to the thread. By interaction I mean if the main program wants to set a variable (say int loc) in the Thread it can do do so by executing worker.loc = 50.

Lastly, here is a program (XXApp.java)  that creates three threads using the approach 1 discussed above.
 

import java.io.*;
import java.lang.Thread;

public class XXApp {
               public static void main( String arrgs[] ) {
                   X worker1 = new X(1); // We create a worker thread to print +1+ continously
                   X worker2 = new X(2); // We create a second worker thread to print +2+ continously
                   X worker3 = new X(3); // We create a third thread to print +3+ continously
                   DoOtherStuff(); // Let the main thread do other stuff
               }
               public static void DoOtherStuff() {
                         while(true)
                                System.out.println("-|-");
               }
            }
class X implements Runnable {
        int ID;
               X(int a) {
                   ID = a;
                   Thread t = new Thread(this);
                   t.start();
               }
               public void run() {
                   Work();  //some code that executes the functionality of the thread
               }
               public void Work() {
                   while(true)
                            System.out.println("+" + ID + "+");
               }
            }