← Back to Multithreading Course

Class 4: Using Lambda Expressions with Runnable

Learn how to write shorter and cleaner code when creating threads using the Runnable interface.

1. Quick Recap: What Did We Learn in Class 3?

In our previous class, we learned about the Runnable interface.

We understood that Runnable represents a task that we want a thread to execute. It has one important method called run().

Let's quickly look at the example from our previous class:

Runnable task = new Runnable() {
    @Override
    public void run() {
        System.out.println("My task is running");
    }
};

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

This code creates a task using Runnable and then gives that task to a Thread. When we call start(), the new thread begins executing the task.

Today, we will learn how to write the same code in a shorter way using Lambda Expressions.

2. What Is a Lambda Expression?

A lambda expression is simply a shorter way of writing certain pieces of Java code.

Instead of writing a complete anonymous class every time, we can use a lambda expression to make the code shorter and easier to read.

Let's understand this with a simple example.

Suppose we have a task that prints a message:

Runnable task = () -> {
    System.out.println("Hello from my task");
};

That's it! We have created a Runnable task using a lambda expression.

The () represents the method parameters. Since the run() method does not accept any parameters, we have empty parentheses.

The -> symbol separates the parameters from the code that we want to execute.

The code inside the curly braces is the actual task.

3. Writing Runnable in Two Different Ways

Let's compare the two approaches so that the difference becomes clear.

Approach 1: Using an Anonymous Class

Runnable task = new Runnable() {
    @Override
    public void run() {
        System.out.println("Hello from my task");
    }
};

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

Approach 2: Using a Lambda Expression

Runnable task = () -> {
    System.out.println("Hello from my task");
};

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

Both examples do exactly the same thing.

The only difference is how we create the Runnable task. The lambda expression allows us to write it with less code.

4. Creating a Thread Directly with a Lambda Expression

We can make the code even shorter.

Instead of first creating a Runnable variable, we can pass the lambda expression directly to the Thread constructor.

Thread thread = new Thread(() -> {
    System.out.println("Hello from a new thread");
});

thread.start();

Let's understand what happens here:

  1. We create a new Thread.
  2. We provide a lambda expression as the task for that thread.
  3. We call start().
  4. The new thread executes the code inside the lambda expression.

Notice that we don't have to explicitly write new Runnable(). Java understands that the lambda expression represents a Runnable task.

5. A Complete Practical Example

Let's create two threads. Each thread will execute a different task.

public class Main {

    public static void main(String[] args) {

        Thread thread1 = new Thread(() -> {
            System.out.println("Task 1 is running");
        });

        Thread thread2 = new Thread(() -> {
            System.out.println("Task 2 is running");
        });

        thread1.start();
        thread2.start();
    }
}

When we run this program, both threads start executing their tasks.

You may see the output in either order:

Task 1 is running
Task 2 is running

Or:

Task 2 is running
Task 1 is running

Both outputs are possible because the operating system and Java runtime decide when each thread gets an opportunity to execute.

The important thing to understand is that we have created two separate tasks and started two separate threads.

6. Can We Use Lambda Expressions for Every Interface?

No. Lambda expressions work with interfaces that have exactly one abstract method.

Runnable is such an interface because it has only one abstract method: run().

For now, remember this simple rule:

A lambda expression can be used when Java expects an interface with exactly one abstract method.

We will explore this idea further when we learn more about Java functional interfaces. For this class, our focus is simply on using lambda expressions with Runnable.

7. Try It Yourself

Create a Java program with two threads using lambda expressions.

  • The first thread should print "Learning Java".
  • The second thread should print "Learning Multithreading".
  • Start both threads using the start() method.

Try writing the program yourself before looking at the earlier examples. Practising small programs is one of the best ways to understand multithreading.

8. Test Your Understanding

Answer these five questions to check what you have learned in this class.

Question 1: What is a lambda expression?

Question 2: Which symbol is used in a lambda expression?

Question 3: Why can we use a lambda expression with Runnable?

Question 4: What does the following code do?

Thread thread = new Thread(() -> {
    System.out.println("Hello");
});

thread.start();

Question 5: What is the main advantage of using a lambda expression with Runnable?

9. Class Summary

Let's quickly revise what we learned today:

  • A lambda expression is a shorter way of writing certain Java code.
  • We can use lambda expressions with Runnable because it has one abstract method.
  • The () -> { } syntax represents a lambda expression with no parameters.
  • We can pass a lambda expression directly to the Thread constructor.
  • We still use start() to start the new thread.

Remember, lambda expressions make our code shorter. They do not change the basic way threads work.

Coming Up Next: Class 5

In our next class, we will understand the current thread and learn how to give names to threads.

We will also see how to find out which thread is currently executing our code.

Your Course Progress

0% Completed

You have completed 4 out of 44 classes.