How to Create and Start a Thread in Java

In this article, we will learn how to create and run a thread in a Java application.

Defining and Starting a Thread

An application that creates an instance of Thread must provide the code that will run in that thread. Java provides two ways to create a thread programmatically.
  1. Implementing the Runnable interface.
  2. Extending the Thread class.

1. Implementing the Runnable interface

The Runnable interface defines a single method, run(), meant to contain the code executed in the thread. The Runnable object is passed to the Thread constructor.
Let's demonstrate how to use Runnable interface with an example.
First, create a Task or WorkerThread using Runnable interface.

WorkerThread.java

public class WorkerThread implements Runnable {
    private String data;
 
    public WorkerThread(final String anyData) {
       this.data = anyData;
    }
 
    @Override
    public void run() {
       for (int i = 0; i < 5; i++) {
           System.out.println("[" + Thread.currentThread().getName() + "] [data=" + 
           this.data + "] Message " + i);
           try {
               Thread.sleep(200);
           } catch (final InterruptedException e) {
               e.printStackTrace();
           }
      }
   }
}
Second, let's see how to use WorkerThread class in the main thread. In this example, the main() method is the main thread which will create another using Above WorkerThread class.
public class InstantiateUsingRunnable {
 
    public static void main(final String[] args) {
  
        System.out.println("Thread main started");
  
        final Thread thread1 = new Thread(new WorkerThread("Process data through Runnable interface")); 
        thread1.start();
        thread1.setName("Demo Thread");
  
        System.out.println("Thread main finished");
    }
}
Output:
Thread main started
Thread main finished
[Demo Thread] [data=Process data through Runnable interface] Message 0
[Demo Thread] [data=Process data through Runnable interface] Message 1
[Demo Thread] [data=Process data through Runnable interface] Message 2
[Demo Thread] [data=Process data through Runnable interface] Message 3
[Demo Thread] [data=Process data through Runnable interface] Message 4

Runnable Interface Example using Anonymous Class

Anonymous classes enable you to make your code more concise. They enable you to declare and instantiate a class at the same time.
public class RunnableExampleUsingAnonymousClass {

    public static void main(final String[] args) {
        System.out.println(" main thread started : " + Thread.currentThread().getName());

        System.out.println("Creating Runnable...");

        final Runnable runnable = new Runnable() {
   
             @Override
             public void run() {
                 System.out.println("Inside : " + Thread.currentThread().getName());
    
             }
        }; 

        System.out.println("Creating Thread...");
        final Thread thread = new Thread(runnable);

        System.out.println("Starting Thread...");
        thread.start();
        
        System.out.println(" main thread ended : " + Thread.currentThread().getName());
    }
}
Output:
 main thread started : main
Creating Runnable...
Creating Thread...
Starting Thread...
 main thread ended : main
Inside  : Thread-0

Runnable Interface Example Using Lambda Expression

The above example can be made even shorter by using Java 8 Lambda Expressions -
public class RunnableExampleUsingLambda {

    public static void main(final String[] args) {
        System.out.println(" main thread started : " + Thread.currentThread().getName());

        System.out.println("Creating Runnable...");

        final Runnable runnable = () -> System.out.println("Inside  : " + Thread.currentThread().getName()); 

        System.out.println("Creating Thread...");
        final Thread thread = new Thread(runnable);

        System.out.println("Starting Thread...");
        thread.start();
        
        System.out.println(" main thread ended : " + Thread.currentThread().getName());
    }
}
Output:
Creating Runnable...
Creating Thread...
Starting Thread...
 main thread ended : main
Inside  : Thread-0

2. Extending the Thread class

You can create a new thread simply by extending your class from java.lang.Thread and overriding it’s run() method.
The run() method contains the code that is executed inside the new thread. Once a thread is created, you can start it by calling the start() method.
Let's demonstrate how to create and start a Thread by extending java.lang.Thread class. 
In this example the main() method is the main thread, we will create and start the WorkerThread in the main thread.
class WorkerThread extends Thread {
     private String anyData;
 
     public WorkerThread(final String anyData) {
          this.anyData = anyData;
     }
 
     @Override
     public void run() {
     for (int i = 0; i < 5; i++) {
          System.out.println("[" + Thread.currentThread().getName() + "] "
          + "[data=" + this.anyData + "] Message " + i);
     try {
         Thread.sleep(200);
     } catch (final InterruptedException e) {
         e.printStackTrace();
     }
   }
}
}


/**
 *  Instantiate a thread by using Thread class.
 *  @author Ramesh fadatare
 **/

public class ThreadExample {
 
    public static void main(final String[] args) {
  
         System.out.println("Thread main started");

         final Thread thread = new WorkerThread("Process data using WorkerThread"); 
         thread.start();
         thread.setName("WorkerThread");
  
         System.out.println("Thread main finished");
    }
}
Output:
Thread main started
Thread main finished
[WorkerThread] [data=Process data using WorkerThread] Message 0
[WorkerThread] [data=Process data using WorkerThread] Message 1
[WorkerThread] [data=Process data using WorkerThread] Message 2
[WorkerThread] [data=Process data using WorkerThread] Message 3
[WorkerThread] [data=Process data using WorkerThread] Message 4

Creating Multiple Threads

In this example, we have created 2 threads, you can create any number of threads that required to satisfy your requirement.
public class ThreadSleepExample {
    public static void main(final String[] args) {
        System.out.println("Thread main started");
        final Thread thread1 = new Thread(new WorkerThread());
        thread1.setName("WorkerThread 1");
        final Thread thread2 = new Thread(new WorkerThread());
        thread1.setName("WorkerThread 2");
        thread1.start();
        thread2.start();
        System.out.println("Thread main ended");
    }
}

class WorkerThread implements Runnable {

    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
        try {
             Thread.sleep(1000);
             System.out.println("[" + Thread.currentThread().getName() + "] Message " + i);
        } catch (final InterruptedException e) {
             e.printStackTrace();
        }
     }
  }
}
Output:
[WorkerThread 2] Message 0
[Thread-1] Message 0
[Thread-1] Message 1
[WorkerThread 2] Message 1
[WorkerThread 2] Message 2
[Thread-1] Message 2
[WorkerThread 2] Message 3
[Thread-1] Message 3
[Thread-1] Message 4
[WorkerThread 2] Message 4

Runnable or Thread, Which one to use?

We have learned how to create and start a thread via implementing Runnable interface and extending java.lang.Thread class. Now it's time to decide which one should we use?
In general, You should always use a Runnable object to create a thread. This method is more flexible. It allows your class to extend from any other class. Also, you can use anonymous class syntax and Java 8’s lambda expression with Runnable to make your code more concise.
The first second, where we created a thread by extending from Thread class is very limited because once you extend your class from Thread, you cannot extend from any other class since Java doesn’t allow multiple inheritance.
Also, If you follow good design practice, Inheritance is meant for extending the functionality of the parent class, but when you create a thread, you don’t extend the functionality of Thread class, you merely provide the implementation of run() method.

Comments