Wednesday, July 27, 2011

Java: Thread Example

Threads allow for different sequences of program execution to run synchronously together within the same program. This allows multiple tasks within the same program to be done faster. This also allows a user to interact with a program running on one thread while intense calculations are running on another.

The following code will created several threads and each thread creates a random object (randObj) to calculates the random numbers 1 or 2. Each time a new thread is created, it displays its number, unique ID and priority number on the screen.

Next, each thread runs a "for" loop for 1000 counts and periodically displays the unique ID of each thread. Each thread is randomly put to sleep for 1 or 2 milliseconds on each loop to simulate the threads performing different tasks.

Once the threads are done looping, the thread number, unique thread ID number and the hash number for each randObj is displayed.

The number of threads defaults to 4 threads if no command line argument is given.


UML Diagram

Click image for larger view.


//RunThreads.java

import java.util.Random;

public class RunThreads
{
  private static int args;
  ThreadX[] threadArray;

  public static void main(String[] arguments)
  {
    if (arguments.length > 0)
    {
      try
      {
        args = Integer.parseInt(arguments[0]);
      }
      catch(NumberFormatException e)
      {
        System.err.println("Argument must be an integer.");
        System.exit(1);
      }
    }
    else
    {
      System.out.println("No arguments given - defaulting to 4 threads.");
      args = 4;
    }
    System.out.println("Thread #main-" + Thread.currentThread());
    System.out.println(Thread.currentThread() + "-" + "Active!");
    RunThreads rt = new RunThreads();
    rt.makeThreads(args);
    System.out.println("Thread #main-" + Thread.currentThread() + "-Done!");
  }

  private void makeThreads(int noThreads)
  {
    threadArray = new ThreadX[noThreads];

    for(int i=0; i < noThreads; i++)
    {
      threadArray[i] = new ThreadX(i);
      threadArray[i].start();
    }
  }

  private class ThreadX extends Thread
  {
    private int tnumber;
    private int rand;
    private Random randObj;

    private void setRand()
    {
      rand = randObj.nextInt(2) + 1;
    }

    ThreadX(int tnumber)
    {
      this.tnumber = tnumber;
      randObj = new Random();
    }

    public void run()
    {
      System.out.println("Thread #" + tnumber + "-" + 
          Thread.currentThread());

      for(int i=0; i < 1000; i++)
      {
        setRand();

        try
        {
          Thread.sleep(rand);
        }
        catch(InterruptedException e)
        {
          //Ignore
        }

        if( i%100 == 0 )
        {
          System.out.println(Thread.currentThread() + "-" + "Active!");
        }
      }
      System.out.println("Thread #" + tnumber + "-" + Thread.currentThread() +
          "-Done!");
      System.out.println("Thread #" + tnumber + "-" + "randObj hash code: " + 
          randObj.hashCode());
    }
  }
}

RunThreads Output

Click image for larger view.

If you run this program, as can be seen by the output, even though each thread is created one after another, they do not execute each line of code in the same order due to the random time each thread sleeps. Even if the threads were not put to sleep at random times, or put to sleep at all, they could still be interrupted by the operating system at varying times for other processes to run on the computer. This can cause the output sequences to vary too.

Since we have several threads of execution, it is common to see 2 or more lines of output occur on the same line. Sometimes the output lines may even interleave. This is normal for separate threads of execution and one would have to add some sort of lock on the output so that all the output from one thread is completed before the output of another thread is sent to the output stream.

1 comment: