Witscale Test Center

12.1 Thread basics > 12.1.1 What is thread?


12.1.1 What is thread?

A Java thread really means a thread-of-execution. In Java, you can specify thread as an object of java.lang.Thread class. Like all other Java objects, the thread object has methods and variables. Imagine thread as a worker who helps you in getting the job done. You need to do following two things with a thread,

         Create a thread object.

         Ask it to do the job. (start the thread)

 

Let us see how to write a Java code to do this.

Create a thread object

A java thread is an object of java.lang.Thread class. This class defines various methods for doing various things to manage thread such as start working (start()), do-nothing for sometime (sleep()) and so on. Remember, the thread object is useful to you only when it does something which you would like it to do. But where would you specify it? Each java thread has a run() method where you can specify the job-to-be-done. Since java.lang.Thread already has run method, you need to redefine this run()method. You can do it in either of the following two ways:

Subclass the Thread class and override its run() method.

Write your own class that implements the java.lang.Runnable interface that has the run()method. Then you can create a thread using an object of this class.

 

Extending java.lang.Thread

You can define a class that extends java.lang.Thread. For example, if you want to create threads that display how many Sundays are present in the current month. For that you need to define a thread class with run() method implementing the logic as:

 

class SundayCalculator extends Thread {

   public void run() {

    // implement the Sunday calculation

    System.out.println(“There are ” + n + “ Sundays in this month”);

   }

}

 

You can create a thread object by instantiating this class as:

 

Thread myThread = new SundayCalculator();

 

Though simple, this approach of extending Thread class is not recommended. The most obvious reason is that when you extend from a Thread class, you cannot extend from any other class. For example, if you want the class SundayCalculator to be extended from a Calendar class, you cannot do that as Java won’t allow you to extend from two classes. Moreover extending from thread can be a poor design choice unless you are really enhancing the Thread class. In most cases, you define a class that extends Thread only to use the run() method. The rest of the inherited behavior from Thread class is never used (or redefined) in the SundayCalculator. Java provides a better alternative of creating thread with the Runnable interface.

 

Implementing java.lang.Runnable

The Thread class can create thread objects from all classes that implement the Runnable interface. This interface has a single method public void run(). Your class becomes runnable if it implements this interface. For example, the SundayCalculator can implement the Runnable interface as:

 

public class SundayCalculator implements Runnable {

     public void run() {

    // implement the Sunday calculation

  System.out.println(“There are ” + n + “ Sundays in this month”);

 }

}

 

Creating a thread object from a runnable object is a little bit trickier. To create a thread, you always need a instance of Thread class. But you want this thread to execute the runnable object’s run method. The Thread class has constructor that accepts an object of Runnable type as an argument. This runnable object is considered as target of thread because when the thread is executed it executes the target object’s run method instead of its own.

You can create a thread object using a runnable object ( as target) by first instantiating the runnable class and then using the instance to create the thread object.

 

SundayCalculator myRunnable = new SundayCalculator();

Thread myThread = new Thread(myRunnable);

 

A thread object created using the Thread constructor public Thread(Runnable) always executes the run method of runnable object instead of its own.

 

Thread constructors

The class Thread has several overloaded constructor besides the one that takes no argument and the one that takes runnable object as argument. Here is the list of important constructor signatures of Thread class.

 

public Thread()

public Thread(Runnable)

public Thread(ThreadGroup, Runnable)

public Thread(String)

public Thread(ThreadGroup, String)

public Thread(Runnable, String)

public Thread(ThreadGroup, Runnable, String)

 

You need to recognize all the thread constructors for the exam. Though ThreadGroup is not officially part of exam objective, you need to know about the thread constructors that takes them as argument.  The constructor argument of type String takes a thread name as argument. The first two constructors in the list are primarily used in this chapter.

 

The thread object is not a thread-of-execution yet.

Creating a thread instance means you created a thread object which knows what to do when it starts executing as a independent process. At this stage the thread object haven’t started doing the job yet. It is an object just like any other Java object and not a thread-of-execution that can run on its own. To make this thread object a real thread, you must start it.

Starting a thread

Once you know how the thread objects are created, the next step is to get them working. One obvious thought running through your mind might be, ‘well, I will simply invoke its run() method’.  In fact, you can invoke the run method of a thread object just like you invoke a method on any Java object. But this method will be executed in the same thread-of-execution in which you are calling it. For example,

 

public class ThreadTester {

     public static void main(String[] args) {

        SundayCalculator myRunnable = new SundayCalculator();

        Thread myThread = new Thread(myRunnable);

        myThread.run();

        System.out.println(“done”);

     }

}

 

In the above example, the thread object performs its job in a single-threaded environment. The ThreadTester is executed sequentially and “done” is not printed until the method myThread.run(); finishes its execution. But we do not want just a single thread-of-execution. What we really want is the myThread to execute in parallel and independent of the main method execution. The thread class has special method called start() method which does just that. This instance method converts a thread object to a independent thread-of-execution. You can start a new thread-of-execution as:

 

public class ThreadTester {

     public static void main(String[] args) {

        SundayCalculator myRunnable = new SundayCalculator();

        Thread myThread = new Thread(myRunnable);

        myThread.start();

        System.out.println(“done”);

     }

}

 

Sometime after the myThread.start(); is invoked, the new thread-of execution starts executing and it invokes the run method of myThread. At the same time, the original thread-of-execution executing the main method will continue its execution. Thus, we have two threads-of-execution running in parallel. The first thread-of-execution main starts after you run the Java application ThreadTester from command prompt. The second thread-of-execution myThread starts after myThread.start(); is invoked in main method. Figure 12.1 illustrates the two threads on a timeline with a running-man’s metaphor.


 

Figure 12.1 Execution of main thread and the thread it creates and starts in the context of time

 

At one point in time, both threads are shown as executing. However the actual execution of threads is somewhat different. Moreover, myThread may not immediately starts running after the main thread executes its start() method. This figure is to show you how you can have two (or more) separate processes (threads-of-execution) that are exists (not necessarily running) parallel in time. We will see all the details of actual thread execution in the following sections. Let us start with what exactly happens when the thread start() method is called.