← Back to Advanced Java Course | Chapter 2: Multithreading | Lesson 3 of 8

Java Runnable Interface

Runnable is a job description that says 'here is the work to do', which a thread can then carry out. It is like writing a task on a card and handing it to a helper.
Syntax
java
class TaskName implements Runnable {
    public void run() {
        // task code
    }
}

Thread thread = new Thread(new TaskName());
thread.start();

What is the Runnable Interface?

The Runnable interface is a functional interface in Java used to represent a task that a thread can execute. It defines a single abstract run() method containing the statements that should run in the background, independent of how that task actually gets scheduled onto a thread.

Example: What is the Runnable Interface?

java
// Define the class Main
public class Main {
	// Define the class Task
	static class Task implements Runnable {
		public void run() {
			// Print a line to the console
			System.out.println("Task executing");
		}
	}
	// Program entry point: the JVM starts running here
	public static void main(String[] args) {
		new Task().run();
	}
}

Implementing Runnable

To implement Runnable, use the implements keyword on your class and provide a body for its run() method. This separates 'what work needs to happen' from 'how it gets executed', since the same Runnable object can be handed to a Thread, an ExecutorService, or anything else that knows how to run one.

Example: Implementing Runnable

java
// Define the class Main
public class Main {
	// Define the class PrintTask
	static class PrintTask implements Runnable {
		public void run() {
			// Print a line to the console
			System.out.println("Work happens here");
		}
	}
	// Program entry point: the JVM starts running here
	public static void main(String[] args) throws InterruptedException {
		// Create a new Thread object and store it in t
		Thread t = new Thread(new PrintTask());
		// Start the thread; it runs in parallel with this code
		t.start();
		// Wait for the thread to finish
		t.join();
	}
}

Creating Threads with Runnable

To actually run a Runnable task, pass your task instance into the Thread constructor rather than extending Thread directly. This creates a Thread object that simply wraps and delegates to your Runnable's run() method when start() is called.

Example: Creating Threads with Runnable

java
// Define the class Main
public class Main {
	// Program entry point: the JVM starts running here
	public static void main(String[] args) throws InterruptedException {
		Runnable task = () -> System.out.println("Runnable passed to Thread");
		// Create a new Thread object and store it in t
		Thread t = new Thread(task);
		// Start the thread; it runs in parallel with this code
		t.start();
		// Wait for the thread to finish
		t.join();
	}
}

Lambda Expressions with Runnable

Since Runnable is a functional interface with exactly one abstract method, you can write compact thread declarations using a lambda expression instead of a full class. This removes the boilerplate of writing an anonymous inner class just to define a single run() body.

Example: Lambda Expressions with Runnable

java
// Define the class Main
public class Main {
	// Program entry point: the JVM starts running here
	public static void main(String[] args) throws InterruptedException {
		// Create a new Thread object and store it in t
		Thread t = new Thread(() -> System.out.println("Lambda instead of anonymous class"));
		// Start the thread; it runs in parallel with this code
		t.start();
		// Wait for the thread to finish
		t.join();
	}
}

Thread vs. Runnable

Implementing Runnable is generally preferred over extending Thread directly, because Java classes can only extend one parent class. Implementing an interface instead leaves your class free to still extend some other class if it ever needs to, which extending Thread would have ruled out.

Example: Thread vs. Runnable

java
// Define the class Main
public class Main {
	// Define the class Worker
	static class Worker extends Thread {
		public void run() { System.out.println("Extends Thread -- can't extend anything else"); }
	}
	static class Job implements Runnable {
		public void run() { System.out.println("Implements Runnable -- free to extend another class"); }
	}
	// Program entry point: the JVM starts running here
	public static void main(String[] args) throws InterruptedException {
		new Worker().start();
		// Create a new thread to run the given task
		new Thread(new Job()).start();
	}
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Calling task.run() directly and thinking a new thread started; you must pass the Runnable to new Thread(task).start().
  2. Expecting run() to return a value or throw a checked exception, when it returns void and cannot declare checked exceptions; use Callable for that.
  3. Sharing one Runnable object between several threads while it changes an instance field without synchronization, causing race conditions.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.