2 Different Ways to Create a Thread in Java

Like most of the modern programming languages, Java provides build-in support for multi-threading. A multithreaded program contains two or more parts that run parallely. Each part of such a program is called as a thread.

A thread in Java is an instance of the Thread class. Java provides 2 different ways in which a thread can be created:

  1. Extending the Thread class.
  2. Implementing the Runnable interface.

In this article we will look at these 2 ways of creating a thread in Java.


Creating a Thread by Extending the Thread Class

As we know a thread in Java is nothing but an object of Thread class, thus the simplest way to create a thread is by extending the Thread class itself.

The code below shows how to create a thread by extending the Thread class:

public class DemoThread extends Thread{
    
    public DemoThread(String threadName) {
        super(threadName);
        this.start();
    }
    
    @Override
    public void run() {
        
        for (int i = 0; i < 10; i++) {
            System.out.println("Current Thread: "+Thread.currentThread().getName());
        }
    }
}

Note that we must override the run() method, when we create our thread, because it is the entry point of the thread, this is where the new thread starts its execution.

Also note that we need to call the thread’s start() method in order to start its execution. The start() method calls the run method to start execution of the thread.

Thread.currentThread() returns the current thread that is executing.

Now we will write a main class to create an instance of our new thread and execute it. The main class in shown below:

public class ThreadMain {
    
    public static void main(String args[]){
        System.out.println("Current Thread :"+ Thread.currentThread().getName());
        DemoThread demoThread = new DemoThread(("1st Demo Thread");
        DemoThread demoThread2 = new DemoThread("2nd Demo Thread");
        System.out.println("Current Thread :"+ Thread.currentThread().getName());
    }
}

The output generated by executing the ThreadMain class is shown below:

Current Thread :main
Current Thread: 1st Demo Thread
Current Thread :main
Current Thread: 1st Demo Thread
Current Thread: 2nd Demo Thread
Current Thread: 1st Demo Thread
Current Thread: 2nd Demo Thread
Current Thread: 1st Demo Thread
Current Thread: 1st Demo Thread
Current Thread: 2nd Demo Thread
Current Thread: 1st Demo Thread
Current Thread: 2nd Demo Thread
Current Thread: 1st Demo Thread
Current Thread: 1st Demo Thread
Current Thread: 1st Demo Thread
Current Thread: 1st Demo Thread
Current Thread: 2nd Demo Thread
Current Thread: 2nd Demo Thread
Current Thread: 2nd Demo Thread
Current Thread: 2nd Demo Thread
Current Thread: 2nd Demo Thread
Current Thread: 2nd Demo Thread

The output shows that the threads executes asynchronously. Note that the output may vary from system to system depending on the context switch (When the CPU decides to switch from one thread to other).


What if we call run() method directly?

Each thread in Java runs in its own thread context, maintains its own call stack. Invoking the start() method lets the JVM know that a new thread should be created.

Invoking the run() method directly will be like a ordinarily call to the method, the code executes synchronously in the current thread context in the current thread call stack


Creating a Thread by Implementing the Runnable Interface

As we know multiple inheritance is not permitted in Java. Thus, creating a thread my extending Thread class restricts us from extending any other class. To overcome this we can create a thread by implementing the Runnable interface. The Runnable interface contains a single run() method which must be overridden by the class implementing it. The run() method will serve as the entry point of the new thread. The run method is shown below:

public void run();

After we create a class that implements Runnable, we will need to instantiate an object of type Thread from within the class. Thread class provides multiple constructors that accepts an object of type Runnable. Thus we pass the current object to Thread’s constructor to create an instance of Thread. Once an object of Thread type is created we should call the start() method to start the thread’s execution. Calling the start() method will in turn call the run() method which is actually the entry point of our new thread.

Shown below is an example which demonstrates how to create a Thread in Java using Runnable interface:

public class DemoThread implements Runnable{
    
    Thread t;
    
    public DemoThread(String threadName) {
        t = new Thread(this, threadName);
        t.start();
    }
    
    @Override
    public void run() {
        
        for (int i = 0; i < 10; i++) {
            System.out.println("Current Thread: "+Thread.currentThread().getName());
        }
    }
}

Note that we have created a new Thread object from within the DemoThread class by passing instance of the class to the Thread constructor. The method call “t.start()” would in turn call the run method and start the execution of the new thread.

To execute the class we can use the same ThreadMain class used earlier.

RELATED ARTICLES

4 Different Ways of Creating an Object in Java

Most of us have created object using new operator in Java. Did you know the other ways to create objects in Java. This article talks about 4 different ways of creating objects in Java.

View Article

Using AutoCloseable with 'try-with-resources'

Java 7 added the java.lang.AutoCloseable interface that developers can implement in their custom classes for using them with try-with-resources.

View Article

Chained Exception

Chained exception is a feature introduced with JDK 1.4, which allow developers to associate an exception with another exception.

View Article

Shallow Cloning and Deep Cloning

Cloning an object can happen in two ways Deep and Shallow Cloning. In shallow cloning only object references are copied while in deep copy actual objects are copied to the newly cloned object.

View Article

Exception Handling in Inheritance

There are certain rules that must be followed while throwing exceptions in inheritance and overriding methods. This article discuss about these rules.

View Article

Garbage Collection in Java

Java Garbage Collector is a boon to Java developers; it allows developers to program without worrying about memory management. This article describes the working of Java Garbage Collector in details.

View Article

Understanding static and final in Java

Java provides various modifiers which when used with variables, methods or classes, provides them with special properties. Static and final are are two such modifiers which are used frequently by Ja..

View Article

Understanding Object Cloning

Java provides the clone() method which can be used to create a copy an object. It creates a new memory location and copies the content of the object being cloned into the new location.

View Article

Try-with-resources Statement in Java 7

Java 7 introduces the new 'try-with-resources' statement which help developers to overcome the tedious task of closing the resources that have been used in the program.

View Article

Varargs: Variable Arguments to Methods

Java 5 introduced a new feature called varargs, which allows methods to accept variable number of arguments. They are useful in cases where the number of arguments to be passed to a method is unknown.

View Article