Multithreading is a powerful feature in Java that allows concurrent execution of two or more threads. A thread is a lightweight sub-process, the smallest unit of processing. Multithreading is used to achieve multitasking, which can improve the performance of applications by making better use of system resources.

Key Concepts

  1. Thread: A thread is a path of execution within a program. Each thread has its own call stack, but they share the same memory space.
  2. Multithreading: The ability to run multiple threads concurrently.
  3. Concurrency: The ability to run several programs or several parts of a program in parallel.
  4. Parallelism: The simultaneous execution of multiple threads.

Benefits of Multithreading

  • Improved Performance: By dividing tasks into smaller threads, programs can run more efficiently.
  • Resource Sharing: Threads share the same memory and resources, which can lead to better resource utilization.
  • Responsiveness: Multithreading can make applications more responsive, especially in user interfaces.
  • Scalability: Multithreading can help applications scale better on multi-core processors.

Creating Threads in Java

There are two main ways to create a thread in Java:

  1. Extending the Thread class
  2. Implementing the Runnable interface

Extending the Thread Class

To create a thread by extending the Thread class, you need to:

  1. Create a new class that extends Thread.
  2. Override the run() method to define the code that should be executed by the thread.
  3. Create an instance of the new class and call the start() method to begin execution.
class MyThread extends Thread {
    public void run() {
        System.out.println("Thread is running...");
    }

    public static void main(String[] args) {
        MyThread thread = new MyThread();
        thread.start(); // Start the thread
    }
}

Implementing the Runnable Interface

To create a thread by implementing the Runnable interface, you need to:

  1. Create a new class that implements Runnable.
  2. Implement the run() method to define the code that should be executed by the thread.
  3. Create an instance of Thread and pass the Runnable object to its constructor.
  4. Call the start() method on the Thread instance to begin execution.
class MyRunnable implements Runnable {
    public void run() {
        System.out.println("Thread is running...");
    }

    public static void main(String[] args) {
        MyRunnable myRunnable = new MyRunnable();
        Thread thread = new Thread(myRunnable);
        thread.start(); // Start the thread
    }
}

Practical Example

Let's create a simple example where we create two threads that print numbers from 1 to 5.

class NumberPrinter extends Thread {
    private String threadName;

    NumberPrinter(String name) {
        threadName = name;
    }

    public void run() {
        for (int i = 1; i <= 5; i++) {
            System.out.println(threadName + ": " + i);
            try {
                Thread.sleep(500); // Sleep for 500 milliseconds
            } catch (InterruptedException e) {
                System.out.println(e);
            }
        }
    }

    public static void main(String[] args) {
        NumberPrinter thread1 = new NumberPrinter("Thread 1");
        NumberPrinter thread2 = new NumberPrinter("Thread 2");

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

Explanation

  • Thread Creation: We create two instances of NumberPrinter, each representing a separate thread.
  • Thread Execution: We start both threads using the start() method.
  • Thread Sleep: The Thread.sleep(500) method pauses the execution of the current thread for 500 milliseconds.

Exercises

Exercise 1: Create a Thread Using Runnable

Create a thread using the Runnable interface that prints "Hello from Runnable" five times.

Solution:

class HelloRunnable implements Runnable {
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println("Hello from Runnable");
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                System.out.println(e);
            }
        }
    }

    public static void main(String[] args) {
        HelloRunnable helloRunnable = new HelloRunnable();
        Thread thread = new Thread(helloRunnable);
        thread.start();
    }
}

Exercise 2: Create Multiple Threads

Create three threads that print their names and numbers from 1 to 3.

Solution:

class MultiThread extends Thread {
    private String threadName;

    MultiThread(String name) {
        threadName = name;
    }

    public void run() {
        for (int i = 1; i <= 3; i++) {
            System.out.println(threadName + ": " + i);
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                System.out.println(e);
            }
        }
    }

    public static void main(String[] args) {
        MultiThread thread1 = new MultiThread("Thread 1");
        MultiThread thread2 = new MultiThread("Thread 2");
        MultiThread thread3 = new MultiThread("Thread 3");

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

Common Mistakes and Tips

  • Not Calling start(): Ensure you call the start() method to begin thread execution. Calling run() directly will not start a new thread.
  • Handling InterruptedException: Always handle InterruptedException when using Thread.sleep().
  • Thread Safety: Be cautious of shared resources. Use synchronization to avoid race conditions.

Conclusion

In this section, we introduced the concept of multithreading in Java, discussed its benefits, and demonstrated how to create threads using both the Thread class and the Runnable interface. We also provided practical examples and exercises to reinforce the concepts. In the next section, we will delve deeper into creating and managing threads, including the thread lifecycle and synchronization.

Java Programming Course

Module 1: Introduction to Java

Module 2: Control Flow

Module 3: Object-Oriented Programming

Module 4: Advanced Object-Oriented Programming

Module 5: Data Structures and Collections

Module 6: Exception Handling

Module 7: File I/O

Module 8: Multithreading and Concurrency

Module 9: Networking

Module 10: Advanced Topics

Module 11: Java Frameworks and Libraries

Module 12: Building Real-World Applications

© Copyright 2024. All rights reserved