Java Language – 41 – Threads and Thread Class

Concurrency and Multithreading – Threads and Thread Class
Introduction

Concurrency and multithreading are essential in Java to execute multiple tasks simultaneously. Java provides a built-in mechanism for creating and managing threads, which are lightweight sub-processes. In this guide, we will explore the basics of threads and the Thread class, allowing you to create and control threads in your Java applications.

Understanding Threads

A thread is the smallest unit of execution in a program. It represents an independent path of execution and shares the same resources as the parent process. In Java, you can create threads using the Thread class. Threads are useful for improving application performance, responsiveness, and handling concurrent tasks.

Creating Threads with the Thread Class

To create a thread using the Thread class, you can extend the class or implement the Runnable interface and override the run() method. Here’s an example of creating a thread by extending the Thread class:


class MyThread extends Thread {
    public void run() {
        System.out.println("This is a thread created by extending the Thread class.");
    }
}

public class ThreadExample {
    public static void main(String[] args) {
        MyThread thread = new MyThread();
        thread.start();
    }
}
Creating Threads with Runnable Interface

Alternatively, you can create threads by implementing the Runnable interface. This approach allows you to share the same Runnable instance among multiple threads. Here’s an example:


class MyRunnable implements Runnable {
    public void run() {
        System.out.println("This is a thread created by implementing the Runnable interface.");
    }
}

public class RunnableExample {
    public static void main(String[] args) {
        MyRunnable myRunnable = new MyRunnable();
        Thread thread = new Thread(myRunnable);
        thread.start();
    }
}
Starting and Executing Threads

To start a thread, you call the start() method on a Thread object. This method initiates the execution of the run() method in a new thread. The thread scheduler determines when the thread runs, and it can switch between multiple threads.

Thread Lifecycle

Threads go through various states in their lifecycle. These states include:

  • New: When a thread is created but not started yet.
  • Runnable: The thread is ready to run, waiting for the CPU.
  • Running: The thread is actively executing.
  • Blocked: The thread is waiting for a resource or condition.
  • Terminated: The thread has finished its execution.
Joining Threads

You can use the join() method to wait for a thread to finish its execution before proceeding with other tasks. This is helpful when you need the results of one thread before another can continue. Here’s an example:


public class JoinExample {
    public static void main(String[] args) throws InterruptedException {
        Thread thread1 = new Thread(() -> {
            System.out.println("Thread 1 is executing.");
        });

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

        thread1.start();
        thread1.join(); // Wait for thread1 to finish.

        thread2.start();
        thread2.join(); // Wait for thread2 to finish.

        System.out.println("Both threads have finished.");
    }
}
Conclusion

Understanding threads and the Thread class is crucial for developing concurrent Java applications. Whether you extend the Thread class or implement the Runnable interface, you can create and control threads to execute tasks concurrently, improving your program’s performance and responsiveness.