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

Related Whitepaper:

Java Essential Training

Author David Gassner explores Java SE (Standard Edition), the language used to build mobile apps for Android devices, enterprise server applications, and more!

The course demonstrates how to install both Java and the Eclipse IDE and dives into the particulars of programming. The course also explains the fundamentals of Java, from creating simple variables, assigning values, and declaring methods to working with strings, arrays, and subclasses; reading and writing to text files; and implementing object oriented programming concepts. Exercise files are included with the course.

Get it Now!  

Examples Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
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.

Sign up for our Newsletter

20,709 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books