Overview:

Lesson 1 Module 7: Multithreading-Introduction to Multithreading introduces the basics of multithreading in Java, a powerful mechanism that enables the concurrent execution of multiple threads. Multithreading is crucial for improving the performance and responsiveness of Java applications, allowing them to perform multiple tasks simultaneously.

Key Concepts:

  1. Multithreading Basics:
    • Definition: Multithreading is the concurrent execution of two or more threads.
    • Purpose: Improves application performance by allowing parallel execution of tasks, particularly useful for tasks that can be performed independently.
  2. Thread Class and Runnable Interface:
    • Thread Class:
      • Definition: The Thread class in Java is a class that provides methods to create and control threads.
      • Purpose: Used for creating and managing threads directly.
    • Runnable Interface:
      • Definition: The Runnable interface is an interface that represents a task that can be executed concurrently.
      • Purpose: Allows the separation of the thread’s task from the thread itself, promoting a cleaner design.
  3. Creating and Managing Threads:
    • Extending Thread Class:
      • Extending the Thread class and overriding the run method to define the thread’s behavior.
    • Implementing Runnable Interface:
      • Implementing the Runnable interface and providing the implementation for the run method.
    • Starting and Joining Threads:
      • Use the start method to begin the execution of a thread.
      • Use the join method to wait for a thread to complete its execution.

Example:

Let’s create a simple program that demonstrates the creation and management of threads in Java. We’ll create both a Thread class and a Runnable interface implementation.

// Extending Thread class
class MyThread extends Thread {
    @Override
    public void run() {
        for (int i = 1; i <= 5; i++) {
            System.out.println("Thread 1 - Count: " + i);
            try {
                Thread.sleep(500); // Simulate some work
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

// Implementing Runnable interface
class MyRunnable implements Runnable {
    @Override
    public void run() {
        for (int i = 1; i <= 5; i++) {
            System.out.println("Thread 2 - Count: " + i);
            try {
                Thread.sleep(500); // Simulate some work
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

public class MultithreadingExample {

    public static void main(String[] args) {
        // Creating threads
        MyThread thread1 = new MyThread();
        Thread thread2 = new Thread(new MyRunnable());

        // Starting threads
        thread1.start();
        thread2.start();

        // Waiting for threads to complete
        try {
            thread1.join();
            thread2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("Main Thread - Execution Completed");
    }
}

In this example, we create two threads—one by extending the Thread class and another by implementing the Runnable interface. Both threads are started and then joined, ensuring that the main thread waits for their completion before continuing.