Ilias Koutsakis

About Ilias Koutsakis

Ilias has graduated from the Department of Informatics and Telecommunications of the National and Kapodistrian University of Athens. He is interested in all aspects of software engineering, particularly data mining, and loves the challenge of working with new technologies. He is pursuing the dream of clean and readable code on a daily basis.

Java Runnable Example

In this example we will take a look into the Runnable interface in Java, and how it can be used in association with the Thread class to create and execute new threads in your program. We will also try to explain what a Runnable is and what’s the difference from Thread, as well as take a look into the different ways that you can implement Runnable in your code.

 

 

 

1. Runnables and Threads

Let’s start by talking about a very common confusion in Java. Runnables are NOT Threads. The Runnable interface is used to define a certain task that we want to execute, and the whole implementation of this task is inside its only method, run() (which accepts no arguments). The Runnable class by itself does not create a separate thread, because this is what Thread actually does.

Thread is used to create a new execution path (a new thread), separate from the main program. By providing a Runnable as an argument to a Thread constructor, you are essentially giving access of the Runnable’s task (defined in the run() method), to a new Thread object. At any time during your program you can start the new thread, by using Thread.start() and the Runnable’s code will start running.

2. Why use Runnable?

Although you have the ability to create new threads by using just the Thread class, which by itself implements the Runnable interface, the suggested and much more accepted approach is to use Runnable for all the logic that we want to provide for our threads. There are certain reasons for that:

  • Modularity: When you run a thread and it finishes running, there is no way to restart it. This could lead to a lot of code duplication in case of multithreading, where you need a certain task to run a number of times. Fortunately, you can create a Runnable instance which can be reused in any number of threads.
  • Ease of use: Runnable only has one method, public void run(). It accepts no arguments and is as simple as possible. Thread has many methods that need to be taken into account making it very cumbersome to work with, and the extra overhead is always an issue.
  • Inheritance: More often than not, you will have to use additional classes (through inheritance) to extend the functionality of your Runnable object. Java does not support multiple inheritance, so it is much more convenient to create a new class which just implements Runnable (and allows to extend another class) than creating a new class that extends Thread and prevents you from inheriting anything else.

3. Runnable implementation and example

There are two ways to implement a Runnable in Java. Let’s take a quick look into them:

  • Inheritance: You can create a class which implements the Runnable interface. You will be forced to implement the run() method, which contains the logic/code of the task, and instantiate it in the standard Java way. You can use pass this as an argument to a Thread instance, as explained above.
  • Anonymous inner class: In some cases you need to run a small snippet of only a few lines of code. In that case, you can always create a new anonymous inner class inside the Thread constructor and implement the run() method there as well. This is of course not modular, and you cannot reuse that code.

Let’s take a look at the code and see both of these ways at work!

MyRunnableImplementation.java

package com.javacodegeeks.runnableexample;

public class MyRunnableImplementation implements Runnable {

    // We are creating anew class that implements the Runnable interface,
    // so we need to override and implement it's only method, run().
    @Override
    public void run() {
        
        // We are creating a simple loop which will run and allow us to take
        // a look into how the different threads run.
        for (int i = 0; i < 5; i++) {
            
            // Thread.currentThread().getName() is used to get the name of the 
            // currently running thread. We can provide a name, if we create
            // the thread ourselves, else it will be given one from the JVM.
            System.out.println(Thread.currentThread().getName() +
                    "\twith Runnable: MyRunnableImplementation runs..." + i);
        }
    }
}

As you can see, we create a class that implements the Runnable interface. In the main program, we will instantiate this class and pass it as an argument to a Thread constructor, which will run the task, which in this context is the loop.

RunnableExampleMain.java

package com.javacodegeeks.runnableexample;


public class RunnableExampleMain {

    public static void main(String[] args) {
        System.out.println("Executing program...");
        
        // Create a new instance of our class that implements the Runnable interface.
        // This class can be provided as an argument to a Thread instance.
        MyRunnableImplementation r = new MyRunnableImplementation();
        
        // Create a new Thread instance, provide the task that we want to run
        // (by providing the Runnable as an argument) and give the thread a name.
        // Now we can use Thread.start() to run it!
        Thread thread1 = new Thread(r, "Thread 1");
        thread1.start();
        
        // We are creating a second thread. Take notice that we are
        // providing the same Runnable, so this thread will run the same task
        // as the first one.
        Thread thread2 = new Thread(r, "Thread 2");
        thread2.start();

        // Create a thread and provide the Runnable argument as an anonymous inner class.
        // Since we are creating the class "on the spot", we need to provide the implementation
        // of the run() method here.
        // This way is faster and more compact, but it lacks reusability.
        Thread thread3 = new Thread(new Runnable() {
            @Override
            public void run() {
                
                // We are doing the same thing as with the MyRunnableImplementation class
                for (int i = 0; i < 5; i++) {
                    System.out.println(Thread.currentThread().getName() +
                            "\twith Runnable: Inner class Runnable runs..." + i);
                }
            }
        }, "Thread 3");
        thread3.start();
    }
}

Take notice here, that we can use the same Runnable on more than one Thread, without an issue. Also, we can implement the Runnable anonymously inside the constructor.

Output:

We have to take into consideration the fact that we are talking about different threads here, which are unpredictable by definition. Depending on the JVM implementation and the running platform’s architecture, the threads can run in any order. In our example specifically, you can see different output variations, because although the threads run concurrently (so when you invoke Thread.start() a new thread starts running in parallel to your main program),  they all have the task to print something to the standard output, and we have no way of knowing which thread will use the output at any given time.

Let’s take a look at two different runs, where we can easily see which thread runs and which Runnable they are using:

Executing program...
Thread 1	with Runnable: MyRunnableImplementation runs...0
Thread 1	with Runnable: MyRunnableImplementation runs...1
Thread 1	with Runnable: MyRunnableImplementation runs...2
Thread 1	with Runnable: MyRunnableImplementation runs...3
Thread 1	with Runnable: MyRunnableImplementation runs...4
Thread 2	with Runnable: MyRunnableImplementation runs...0
Thread 2	with Runnable: MyRunnableImplementation runs...1
Thread 2	with Runnable: MyRunnableImplementation runs...2
Thread 2	with Runnable: MyRunnableImplementation runs...3
Thread 2	with Runnable: MyRunnableImplementation runs...4
Thread 3	with Runnable: Inner class Runnable runs...0
Thread 3	with Runnable: Inner class Runnable runs...1
Thread 3	with Runnable: Inner class Runnable runs...2
Thread 3	with Runnable: Inner class Runnable runs...3
Thread 3	with Runnable: Inner class Runnable runs...4

Pretty standard, the output is what someone would possibly expect. Take notice that the two first threads used the same instance of MyRunnableImplementation with no issues, while the third one used the inner class. However, after running it again for a couple of times, we got this output:

Executing program...
Thread 1	with Runnable: MyRunnableImplementation runs...0
Thread 1	with Runnable: MyRunnableImplementation runs...1
Thread 1	with Runnable: MyRunnableImplementation runs...2
Thread 1	with Runnable: MyRunnableImplementation runs...3
Thread 1	with Runnable: MyRunnableImplementation runs...4
Thread 3	with Runnable: Inner class Runnable runs...0
Thread 3	with Runnable: Inner class Runnable runs...1
Thread 3	with Runnable: Inner class Runnable runs...2
Thread 2	with Runnable: MyRunnableImplementation runs...0
Thread 2	with Runnable: MyRunnableImplementation runs...1
Thread 3	with Runnable: Inner class Runnable runs...3
Thread 3	with Runnable: Inner class Runnable runs...4
Thread 2	with Runnable: MyRunnableImplementation runs...2
Thread 2	with Runnable: MyRunnableImplementation runs...3
Thread 2	with Runnable: MyRunnableImplementation runs...4

Pretty cool, right? Well, yes, but threads can sometimes cause a real headache, and in many cases you need to know in which order they run. Luckily, Java contains ways of achieving synchronization and scheduling, which are out of the scope of this tutorial.

4. Download the example

This was an example of the Runnable interface in Java.
Download the Eclipse project of this tutorial here: RunnableExample

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

JPA Mini Book

Learn how to leverage the power of JPA in order to create robust and flexible Java applications. With this Mini Book, you will get introduced to JPA and smoothly transition to more advanced concepts.

JVM Troubleshooting Guide

The Java virtual machine is really the foundation of any Java EE platform. Learn how to master it with this advanced guide!

Given email address is already subscribed, thank you!
Oops. Something went wrong. Please try again later.
Please provide a valid email address.
Thank you, your sign-up request was successful! Please check your e-mail inbox.
Please complete the CAPTCHA.
Please fill in the required fields.
Examples Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Examples Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Examples Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close