Runnable Interface in Java to Create Threads

In this article, we will learn the Runnable interface in Java, which is a core element of Java when working with threads. Any class in Java that intends to execute threads must implement the Runnable interface.

In this article, we will provide you a complete insight into the Runnable interface of Java, along with the examples. So, let us start the tutorial with the introduction to the Runnable interface in Java.

Runnable Interface in Java

Runnable Interface in Java

Runnable interface of Java is present in the java.lang package. It is a type of functional interface that provides a primary template for objects that we want to implement using threads.

We know that there are two ways to start a new Thread: Extending the Thread class and implementing the Runnable interface. There is no need to extend or subclass a Thread class when we can perform a task by overriding only the run() method of the Runnable interface.

Hence the Runnable interface provides a way for a class to be active without extending the Thread class. We need to instantiate an object of the Thread and pass it in as the target.

We mostly implement the Runnable interface when using no other method than the run() method. The Runnable interface defines only one method run() with no arguments and holds the code that needs to be executed by the thread.

Thus the classes implementing the Runnable interface need to override the run() method.

run() Method of Runnable Interface

The runnable interface has an undefined method run(). run() has void as return type, and it takes in no arguments. Below table shows the summary of the run() method:

Method Description
public void run() The run() method takes no arguments. When the object of a class that implements the Runnable interface creates a thread, then the run() method is invoked in the thread, and this method executes separately.

Steps to Create New Thread using Runnable Interface

There are following steps to create a new thread using the Runnable interface:

1. The first step is to create a Java class that implements the Runnable interface.
2. The second step is to override the run() method of the Runnable() interface in the class.
3. Now, pass the Runnable object as a parameter to the constructor of the object of the Thread class while creating it. Now, this object is capable of executing the Runnable class.
4. Finally, invoke the start method of the Thread object.

Implementing Runnable Interface

Implementing a Runnable interface is the easiest way to create a thread. We can create a thread on any object by implementing the Runnable interface. To implement a Runnable, we only have to implement the run() method.

In this method, there is a code that we want to execute on a concurrent thread. We can use variables, instantiate classes, and perform an action in the run() method the same way the main thread does. The thread remains active until the return of this method.

The run() method establishes an entry point to a new thread.

Code to implement Runnable interface in Java:

package com.techvidvan.runnableinterface;
public class RunnableDemo {
  public static void main(String[] args) {
    System.out.println("From main() method: " + Thread.currentThread().getName());
    System.out.println("Creating Runnable Instance");
    Runnable runnable = new Runnable() {@Override
      public void run() {
        System.out.println("From run() method: " + Thread.currentThread().getName());
      }
    };

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

    System.out.println("Launching the thread...");
    thread.start();
  }
}

Output:

From main() method: main
Creating Runnable Instance
Creating a Thread Instance
Launching the thread…
From run() method: Thread-0

What happens when Runnable encounters an exception?

The Runnable interface can not throw checked exceptions but it can throw RuntimeException from the run() method. The exception handler of the thread handles the uncaught exceptions if JVM is unable to handle or catch them. It also prints the stack trace and terminates the program flow.

Example:

import java.io.FileNotFoundException;
public class RunnableDemo {
  public static void main(String[] args) {
    System.out.println("The main thread is: " + Thread.currentThread().getName());
    Thread t1 = new Thread(new RunnableDemo().new RunnableImplementation());
    t1.start();
  }
  private class RunnableImplementation implements Runnable {
    public void run() {
      System.out.println(Thread.currentThread().getName() + ", executing the run() method!");
      try {
        throw new FileNotFoundException();
      }
      catch(FileNotFoundException e) {
        System.out.println("Must catch an exception here!");
        e.printStackTrace();
      }
    }
  }
}

Output:

The main thread is: main
Thread-0, executing the run() method!
Must catch an exception here!
java.io.FileNotFoundException
at RunnableDemo$RunnableImplementation.run(Example.java:21)
at java.lang.Thread.run(Thread.java:748)

The above output shows that Runnable class can not throw checked exceptions which is FileNotFoundException in this case. It should handle the checked exceptions in the run() method but JVM automatically handles the RuntimeExceptions.

Use of Runnable class in network programming

The Runnable class can also perform multi-thread programming, especially on the server-side because a server may be getting several requests from different clients. We use multi-thread programming to tackle this in a fast and resource-efficient way.

Example of a networking program using Runnable:

The following program shows a server program which creates a thread, then creates a socket and waits for a client to connect to it and asks for an input string-

import java.io. * ;
import java.net. * ;
public class Example {
  public static void main(String[] args) {
    new Thread(new SimpleServer()).start();
  }
  static class SimpleServer implements Runnable {@Override
    public void run() {
      ServerSocket serverSocket = null;
      while (true) {
        try {
          serverSocket = new ServerSocket(3333);
          Socket clientSocket = serverSocket.accept();

          BufferedReader inputReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
          System.out.println("Client said :	" + inputReader.readLine())
        }
        catch(IOException e) {
          e.printStackTrace();
        }
        finally {
          try {
            serverSocket.close();
          }
          catch(IOException e) {
            e.printStackTrace();
          }
        }
      }
    }
  }
}

Thread class vs. Runnable interface

Thread class vs Runnable interface in java

There are many differences between the Thread class and Runnable interface on the basis of their performance, memory usage, and composition.

  • There is the overhead of additional methods by extending the thread class. They consume excess or indirect memory, computation time, or other resources.
  • As we can only extend one class in Java, therefore, if we extend Thread class, then we can not extend any other class. Therefore, we should prefer to implement the Runnable interface to create a thread.
  • The Runnable interface makes the code more flexible. And, if we are extending a thread, then our code will only be in a thread. Whereas, if we implement the runnable interface, we can pass it in various executor services or to the single-threaded environment.
  • The maintenance of the code becomes easy if we implement the Runnable interface.

Conclusion

Here, we come to the end of the article. We learned about the Runnable interface in Java which is very important in creating threads in Java. It is more preferable as compared to the Thread class in Java when creating the threads.

We discussed the steps to create the thread using the Runnable interface in Java. We hope you might have understood the concept of the Runnable interface in Java.