Home RoadMap Blog Contact us Learn

8.Core Java Concepts: Multithreading

Core Java Concepts: Multithreading

Multithreading in Java allows the concurrent execution of two or more threads, enabling the program to perform multiple tasks simultaneously. This section covers the basics of creating and managing threads, their lifecycle, synchronization, and inter-thread communication.

1. Creating Threads (Thread Class, Runnable Interface)

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

  • By extending the Thread class
  • By implementing the Runnable interface

1.1 Extending the Thread Class

class MyThread extends Thread {
    public void run() {
        System.out.println("Thread is running...");
    }

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

1.2 Implementing the Runnable Interface

class MyRunnable implements Runnable {
    public void run() {
        System.out.println("Runnable thread is running...");
    }

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

2. Thread Lifecycle

The lifecycle of a thread consists of several states:

  • New: When a thread is created but not yet started.
  • Runnable: After the start() method is invoked, the thread enters this state.
  • Blocked/Waiting: When a thread is waiting for resources or other threads.
  • Timed Waiting: When a thread is waiting for a specific period.
  • Terminated: When a thread completes its execution or is interrupted.

3. Synchronization

In a multithreading environment, synchronization ensures that only one thread can access a shared resource at a time to prevent data inconsistency. You can use the synchronized keyword to achieve synchronization.

class Counter {
    private int count = 0;

    public synchronized void increment() {
        count++;
    }

    public int getCount() {
        return count;
    }
}

class MyThread extends Thread {
    Counter counter;

    MyThread(Counter counter) {
        this.counter = counter;
    }

    public void run() {
        for (int i = 0; i < 1000; i++) {
            counter.increment();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Counter counter = new Counter();
        MyThread t1 = new MyThread(counter);
        MyThread t2 = new MyThread(counter);

        t1.start();
        t2.start();

        t1.join();
        t2.join();

        System.out.println("Final count: " + counter.getCount());
    }
}

4. Inter-thread Communication

Inter-thread communication allows threads to communicate with each other via the wait(), notify(), and notifyAll() methods. These methods are used in synchronization to make threads wait or notify them when a condition is met.

class SharedResource {
    private boolean isDataReady = false;

    public synchronized void produceData() throws InterruptedException {
        while (isDataReady) {
            wait();
        }
        System.out.println("Producing data...");
        isDataReady = true;
        notify();
    }

    public synchronized void consumeData() throws InterruptedException {
        while (!isDataReady) {
            wait();
        }
        System.out.println("Consuming data...");
        isDataReady = false;
        notify();
    }
}

class Producer extends Thread {
    SharedResource resource;

    Producer(SharedResource resource) {
        this.resource = resource;
    }

    public void run() {
        try {
            resource.produceData();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

class Consumer extends Thread {
    SharedResource resource;

    Consumer(SharedResource resource) {
        this.resource = resource;
    }

    public void run() {
        try {
            resource.consumeData();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        SharedResource resource = new SharedResource();
        Producer producer = new Producer(resource);
        Consumer consumer = new Consumer(resource);

        producer.start();
        consumer.start();

        producer.join();
        consumer.join();
    }
}
Quick Exercise: Create a multithreaded program where one thread prints odd numbers and another thread prints even numbers from 1 to 100.

Conclusion

Multithreading is a powerful feature of Java that allows you to perform multiple tasks simultaneously. It's especially useful in Selenium automation for running parallel tests, improving performance, and reducing execution time.

Multithreading in Java

Recent Posts