The Runnable InterfaceS2C Home « The Runnable Interface

In the last lesson we saw how to run parts of a program concurrently by subclassing the Thread class. The second way of running parts of a program concurrently is by declaring a class that implements the Runnable interface and is the subject of this lesson.

We saw various examples of thread usage and we we also looked at some of the methods that are available within the Thread class in the last lesson. The Java API offers us an alternative to subclassing the Thread class, which offers us certain advantages when used. When we subclass the Thread class our threads have to inherit from Thread and therefore we are not only limited to that classes functionality but can't extend anything else. Fortunately for us we can also execute independent threads by implementing the Runnable interface which declares a single run() method that gets executed when the thread is started. Using this approach we are free to extend another class if we need to for added functionality.

This is possible because several of the Thread classes overloaded constructors accept a Runnable object as a parameter. So as long as we implement this interface and use our implementing class in the threads construction, then the thread knows to use the implementing classes overridden run() method when the thread is started.

Thread Methods OverviewTop

The table below shows the declarations of the methods of the Thread class used in this lesson:

Method Declaration Description
public static Thread currentThread()Returns a reference to the currently executing thread object.
public final boolean isDaemon()Test if this is a daemon thread.
public final String getName()Obtains and returns the name of the thread.
public final void join()Waits for current thread to die.
public void run()If this thread was constructed using a subclass of the Thread class this method does nothing and should be overridden in the subclass.
If this thread was constructed using a separate Runnable run object, then that Runnable object's run() method is called.
public final void setDaemon(boolean on)Marks this thread as a daemon thread if on set to true, or a user thread when on set to false.
public void start()The JVM calls the run() method of this thread, so it can begin execution.

We will go through the methods mentioned in much greater detail as we go through this lesson. Use the links in the table above to go to the code example where the method is first used.

Creating A Single ThreadTop

To see how we can use threads via the Runnable interface we will recreate the first two examples of thread subclassing from the last lesson. We will keep it simple to begin with, so lets start by creating a single thread using the Runnable interface:


/*
  Create a single thread
*/
public class TestRunnableSingleThread implements Runnable {
    
    // Override run() method of Runnable interface to execute a new thread
    public void run() {
        // Get current active thread
        Thread activeThread = Thread.currentThread();
        System.out.println("The thread named: " + activeThread.getName() + " is starting.");
        System.out.println("Is this a daemon thread? " + activeThread.isDaemon());
        System.out.println("The thread named: " + activeThread.getName() + " is ending.");
    }
    
    public static void main(String[] args) {
        System.out.println("Main user thread has started.");
        // Create a new thread passing across a Runnable object of this class
        Thread th = new Thread(new TestRunnableSingleThread(), "Thread1");
        // Power up the thread via the start() method
        th.start();
        System.out.println("Main user thread has ended.");
    }
}

Save, compile and run the TestRunnableSingleThread class in directory   c:\_Concurrency in the usual way.

test runnable single thread

The first thing we do in the TestRunnableSingleThread class is to implement the Runnable interface. We override the run() method from the Runnable interface. In our main() method, we use our implementing class in the construction of a Thread object of TestRunnableSingleThread class, so the thread knows to use the implementing classes overridden run() method when the thread is started. We then call the start() method on this object, which causes our overriden run() method to be invoked. Our override of the run() method uses the static currentThread() method of the Thread class to get a reference to the active thread. We use the reference to get various information about the thread which we use to outputs a few messages showing the thread name and a test to see if this is a daemon thread.

Creating Multiple ThreadsTop

Ok, we have seen how to create a single thread using the Runnable interface. It is now time to look at creating multiple threads within a program using the Runnable interface:


/*
  Create multiple threads
*/
public class TestRunnableMutipleThread implements Runnable {
    
    // Override run() method of Runnable interface to execute a new thread
    public void run() {
        // Get current active thread
        Thread activeThread = Thread.currentThread();
        System.out.println("The thread named: " + activeThread.getName() + " is starting.");
        System.out.println(activeThread.getName() + " a daemon thread? " + activeThread.isDaemon());
        System.out.println("The thread named: " + activeThread.getName() + " is ending.");
    }
    
    public static void main(String[] args) {
        System.out.println("Main user thread has started.");
        // Create a new thread
        Thread th1 = new Thread(new TestRunnableMutipleThread(), "Thread1");
        Thread th2 = new Thread(new TestRunnableMutipleThread(), "Thread2");
        Thread th3 = new Thread(new TestRunnableMutipleThread(), "Thread3");
        // Power up the threads via the start() method
        th1.start();
        th2.setDaemon(true);
        th2.start();
        th3.start();
        System.out.println("Main user thread has ended.");
    }
}

Save, compile and run the TestRunnableMutipleThread class in directory   c:\_Concurrency in the usual way.

test runnable multiple thread

As with all the examples in this section where we use multiple threads, the output you get may vary from our screenshots as we have limited control over the order in which the threads are run.

The first thing we do in the TestRunnableMutipleThread class is to implement the Runnable interface. We override the run() method from the Runnable interface. In our main() method, we use our implementing class in the construction of three Thread objects of TestRunnableMutipleThread class, so the thread knows to use the implementing classes overridden run() method when the threads are started. We then call the start() method on these object, which causes our overriden run() method to be invoked. Our override of the run() method uses the static currentThread() method of the Thread class to get a reference to the active thread. We use the reference to get various information about the thread which we use to outputs a few messages showing the thread name and a test to see if this is a daemon thread.

Connecting ThreadsTop

We have mentioned several times that we have limited control over the order in which the threads are run, but we do have some control. As we showed in the previous lesson, we can cease execution of a thread for a specified amount of time using the sleep() method. We can also use the yield() method, to cease execution of a thread up to a specified amount of time,and there are also options to prioritize and lock threads, all of which we will look at in later lessons of this section.

The join() MethodTop

There is another option available to us, the join() method of the Thread class which we will take a closer look at now. The join() method allows us to connect the current thread to a named thread, which is very handy when we want to guarantee that one thread finishes before another. The code below shows an example of using the join() method:


/*
  Connecting threads using the join() method
*/
public class TestConnectThread implements Runnable {
    
    // Override run() method of Runnable interface to execute a new thread
    public void run() {
        // Get current active thread
        Thread activeThread = Thread.currentThread();
        System.out.println("The thread named: " + activeThread.getName() + " is starting.");
        System.out.println(activeThread.getName() + " a daemon thread? " + activeThread.isDaemon());
        System.out.println("The thread named: " + activeThread.getName() + " is ending.");
    }
    
    public static void main(String[] args) {
        System.out.println("Main user thread: " + Thread.currentThread().getName() + " has started.");
        // Create a new thread
        Thread th1 = new Thread(new TestConnectThread(), "Thread1");
        Thread th2 = new Thread(new TestConnectThread(), "Thread2");
        Thread th3 = new Thread(new TestConnectThread(), "Thread3");
        // Power up the threads via the start() method
        th1.start();
        // join() main thread to 'th1' so if finishes after 'th1' dies
        try {
            th1.join();
        } catch (InterruptedException ex) {
            System.out.println(Thread.currentThread().getName() + ": " + ex);
        } 

        th2.setDaemon(true);
        th2.start();
        th3.start();
        System.out.println("Main user thread: " + Thread.currentThread().getName() + " has ended.");
    }
}

Save, compile and run the TestConnectThread class in directory   c:\_Concurrency in the usual way.

test join threads

The first thing we do in the TestConnectThread class is to implement the Runnable interface. We override the run() method from the Runnable interface. In our main() method, we use our implementing class in the construction of three Thread objects of TestRunnableMutipleThread class, so the thread knows to use the implementing classes overridden run() method when the threads are started. We then call the start() method on 'th1' and use the join() method on the currently executing thread. We are in the main() method so the active thread is the user thread that was kicked off when we started the JVM, so is the thread named 'main'.

In essence what the join() method is doing is moving the thread called 'main' to a blocked state, in which it will remain until the 'th1' thread dies. If we were to use the join() method in the overridden run() method then the current thread could be any of the new threads created if they have been started.

We then call the start() method on the other two threads we created. Our override of the run() method uses the static currentThread() method of the Thread class to get a reference to the active thread. We use the reference to get various information about the thread which we use to output a few messages showing the thread name and a test to see if this is a daemon thread. As you can see from the output the 'th1' (thread1) thread completes before the main thread does. This will always be the case whatever order the threads start the run() method in, because of the connection we made.

Lesson 2 Complete

In this lesson we looked at the second way of running parts of a program concurrently by declaring a class that implements the Runnable interface.

What's Next?

In the next lesson we look at synchronization and how we can control access to our code at the method or block level.

go to home page Homepage go to top of page Top