WikiGalaxy

Personalize

Introduction to Java Threads

What is a Thread?

In Java, a thread is the smallest unit of processing. It is a lightweight subprocess, a small unit of process, and is part of a process. Threads are independent, and if there is an exception in one thread, it does not affect other threads.


public 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();
    }
}
        

Console Output:

Thread is running...

Implementing Runnable Interface

Runnable Interface

The Runnable interface should be implemented by any class whose instances are intended to be executed by a thread. The class must define a method of no arguments called run.


public class MyRunnable implements Runnable {
    public void run() {
        System.out.println("Thread is running using Runnable...");
    }
    public static void main(String[] args) {
        Thread t1 = new Thread(new MyRunnable());
        t1.start();
    }
}
        

Console Output:

Thread is running using Runnable...

Thread Lifecycle

Lifecycle of a Thread

A thread can be in one of the following states: New, Runnable, Running, Blocked, and Terminated. Understanding these states helps in managing thread behavior.


// Example showing thread states
class MyThread extends Thread {
    public void run() {
        System.out.println("Thread is running...");
    }
    public static void main(String[] args) {
        MyThread t1 = new MyThread();
        System.out.println("State: " + t1.getState()); // NEW
        t1.start();
        System.out.println("State: " + t1.getState()); // RUNNABLE
    }
}
        

Console Output:

State: NEW

Thread is running...

State: RUNNABLE

Thread Priority

Setting Thread Priority

Java allows you to set the priority of a thread using the setPriority() method. Threads with higher priority are executed in preference to threads with lower priority.


class PriorityThread extends Thread {
    public void run() {
        System.out.println("Running thread name: " + Thread.currentThread().getName());
        System.out.println("Running thread priority: " + Thread.currentThread().getPriority());
    }
    public static void main(String[] args) {
        PriorityThread t1 = new PriorityThread();
        PriorityThread t2 = new PriorityThread();
        t1.setPriority(Thread.MIN_PRIORITY);
        t2.setPriority(Thread.MAX_PRIORITY);
        t1.start();
        t2.start();
    }
}
        

Console Output:

Running thread name: Thread-0

Running thread priority: 1

Running thread name: Thread-1

Running thread priority: 10

Thread Synchronization

Why Synchronization?

Synchronization in Java is the capability to control the access of multiple threads to shared resources. Without synchronization, it is possible for one thread to modify a shared variable while another thread is in the process of using or updating the same variable.


class Counter {
    private int count = 0;
    public synchronized void increment() {
        count++;
    }
    public int getCount() {
        return count;
    }
}
public class SyncExample {
    public static void main(String[] args) {
        Counter counter = new Counter();
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                counter.increment();
            }
        });
        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                counter.increment();
            }
        });
        t1.start();
        t2.start();
        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Count: " + counter.getCount());
    }
}
        

Console Output:

Count: 2000

Inter-Thread Communication

Communication Between Threads

Inter-thread communication or Co-operation is all about allowing synchronized threads to communicate with each other. It is implemented using wait(), notify(), and notifyAll() methods.


class SharedResource {
    private boolean available = false;
    public synchronized void produce() throws InterruptedException {
        while (available) {
            wait();
        }
        System.out.println("Produced!");
        available = true;
        notify();
    }
    public synchronized void consume() throws InterruptedException {
        while (!available) {
            wait();
        }
        System.out.println("Consumed!");
        available = false;
        notify();
    }
}
public class InterThreadComm {
    public static void main(String[] args) {
        SharedResource resource = new SharedResource();
        Thread producer = new Thread(() -> {
            try {
                resource.produce();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        Thread consumer = new Thread(() -> {
            try {
                resource.consume();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        producer.start();
        consumer.start();
    }
}
        

Console Output:

Produced!

Consumed!

Deadlock in Threads

Understanding Deadlocks

Deadlock describes a situation where two or more threads are blocked forever, waiting for each other. This occurs when multiple threads need the same locks but obtain them in different orders.


class A {
    synchronized void foo(B b) {
        System.out.println("Thread 1 starts execution of foo()");
        try {
            Thread.sleep(100);
        } catch (Exception e) {}
        b.last();
    }
    synchronized void last() {
        System.out.println("Inside A's last() method");
    }
}
class B {
    synchronized void bar(A a) {
        System.out.println("Thread 2 starts execution of bar()");
        try {
            Thread.sleep(100);
        } catch (Exception e) {}
        a.last();
    }
    synchronized void last() {
        System.out.println("Inside B's last() method");
    }
}
public class Deadlock {
    public static void main(String[] args) {
        final A a = new A();
        final B b = new B();
        Thread t1 = new Thread(() -> a.foo(b));
        Thread t2 = new Thread(() -> b.bar(a));
        t1.start();
        t2.start();
    }
}
        

Console Output:

Thread 1 starts execution of foo()

Thread 2 starts execution of bar()

Volatile Keyword

Using Volatile

The volatile keyword in Java is used to indicate that a variable's value will be modified by different threads. Declaring a volatile Java variable means that it can be changed unexpectedly by other parts of the program.


class VolatileExample extends Thread {
    private volatile boolean running = true;
    public void run() {
        while (running) {
            System.out.println("Thread is running...");
        }
    }
    public void stopRunning() {
        running = false;
    }
    public static void main(String[] args) {
        VolatileExample t = new VolatileExample();
        t.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        t.stopRunning();
        System.out.println("Thread stopped.");
    }
}
        

Console Output:

Thread is running...

Thread stopped.

Thread Pooling

Understanding Thread Pools

A thread pool reuses previously created threads to execute current tasks and offers a solution to the problem of thread cycle overhead and resource thrashing.


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

class WorkerThread implements Runnable {
    private String message;
    public WorkerThread(String s) {
        this.message = s;
    }
    public void run() {
        System.out.println(Thread.currentThread().getName() + " (Start) message = " + message);
        processMessage();
        System.out.println(Thread.currentThread().getName() + " (End)");
    }
    private void processMessage() {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public class ThreadPoolExample {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(5);
        for (int i = 0; i < 10; i++) {
            Runnable worker = new WorkerThread("" + i);
            executor.execute(worker);
        }
        executor.shutdown();
        while (!executor.isTerminated()) {}
        System.out.println("Finished all threads");
    }
}
        

Console Output:

pool-1-thread-1 (Start) message = 0

pool-1-thread-1 (End)

Finished all threads

logo of wikigalaxy

Newsletter

Subscribe to our newsletter for weekly updates and promotions.

Privacy Policy

 • 

Terms of Service

Copyright © WikiGalaxy 2025