WikiGalaxy

Personalize

Introduction to Threads

What are Threads?

  • Threads are the smallest unit of processing that can be scheduled by an operating system.
  • They allow multiple tasks to run concurrently within a single process.
  • Threads share the same memory space but can execute independently.

Benefits of Using Threads

  • Improved application performance through parallelism.
  • Efficient utilization of CPU resources.
  • Faster execution of tasks due to concurrent execution.

Challenges with Threads

  • Complexity in managing and synchronizing threads.
  • Potential for race conditions and deadlocks.
  • Difficulty in debugging multithreaded applications.

Thread Life Cycle

  • New: Thread is created but not yet started.
  • Runnable: Thread is ready to run and waiting for CPU time.
  • Blocked/Waiting: Thread is waiting for a resource or event.
  • Terminated: Thread has completed execution.

Types of Threads

  • User-level threads: Managed by user-level libraries.
  • Kernel-level threads: Managed directly by the operating system.

Creating Threads in Java

Using the Thread Class

Threads in Java can be created by extending the Thread class and overriding its run() method.


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

public class Main {
    public static void main(String args[]) {
        MyThread t1 = new MyThread();
        t1.start();
    }
}
        

Using the Runnable Interface

Threads can also be created by implementing the Runnable interface and passing it to a Thread object.


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

public class Main {
    public static void main(String args[]) {
        Thread t1 = new Thread(new MyRunnable());
        t1.start();
    }
}
        

Using Lambda Expressions

Java 8 onwards, threads can be created using lambda expressions for a more concise syntax.


public class Main {
    public static void main(String args[]) {
        Thread t1 = new Thread(() -> System.out.println("Thread is running."));
        t1.start();
    }
}
        

Thread Synchronization

Why Synchronization is Important

  • Ensures that shared resources are accessed by only one thread at a time.
  • Prevents data inconsistency and race conditions.

Synchronized Methods

Methods can be synchronized to ensure that only one thread can execute them at a time.


class Counter {
    private int count = 0;

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

    public int getCount() {
        return count;
    }
}

public class Main {
    public static void main(String args[]) {
        Counter counter = new Counter();
        // Threads accessing synchronized method
    }
}
        

Synchronized Blocks

Synchronized blocks can be used to synchronize specific sections of code rather than entire methods.


class Counter {
    private int count = 0;

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

    public int getCount() {
        return count;
    }
}

public class Main {
    public static void main(String args[]) {
        Counter counter = new Counter();
        // Threads accessing synchronized block
    }
}
        

Thread Communication

Inter-thread Communication

  • Allows threads to communicate with each other using wait(), notify(), and notifyAll() methods.
  • Helps in coordinating the execution of threads.

class SharedResource {
    private boolean available = false;

    public synchronized void produce() throws InterruptedException {
        while (available) {
            wait();
        }
        available = true;
        notify();
    }

    public synchronized void consume() throws InterruptedException {
        while (!available) {
            wait();
        }
        available = false;
        notify();
    }
}
        

Thread Pools

What are Thread Pools?

  • A collection of pre-instantiated reusable threads.
  • Helps in managing a large number of threads efficiently.

Advantages of Thread Pools

  • Reduces the overhead of thread creation and destruction.
  • Improves the performance of applications with many short-lived tasks.

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Main {
    public static void main(String args[]) {
        ExecutorService executor = Executors.newFixedThreadPool(5);
        for (int i = 0; i < 10; i++) {
            executor.execute(new RunnableTask());
        }
        executor.shutdown();
    }
}

class RunnableTask implements Runnable {
    public void run() {
        System.out.println("Task executed by " + Thread.currentThread().getName());
    }
}
        

Deadlocks

Understanding Deadlocks

  • A situation where two or more threads are blocked forever, waiting for each other.
  • Occurs when multiple threads need the same locks but obtain them in different orders.

class Resource {
    synchronized void methodA(Resource r) {
        System.out.println("Thread 1: Holding lock on Resource 1...");
        try { Thread.sleep(100); } catch (InterruptedException e) {}
        System.out.println("Thread 1: Waiting for lock on Resource 2...");
        r.methodB(this);
    }

    synchronized void methodB(Resource r) {
        System.out.println("Thread 2: Holding lock on Resource 2...");
        try { Thread.sleep(100); } catch (InterruptedException e) {}
        System.out.println("Thread 2: Waiting for lock on Resource 1...");
        r.methodA(this);
    }
}

public class Main {
    public static void main(String args[]) {
        Resource r1 = new Resource();
        Resource r2 = new Resource();
        
        new Thread(() -> r1.methodA(r2)).start();
        new Thread(() -> r2.methodB(r1)).start();
    }
}
        
logo of wikigalaxy

Newsletter

Subscribe to our newsletter for weekly updates and promotions.

Privacy Policy

 • 

Terms of Service

Copyright © WikiGalaxy 2025