← Back to Courses
© 2025 sampathirao yoganandh
Week 12 · CO-3

Multithreading

Thread creation, lifecycle, priorities, synchronization, and inter-thread communication  CO-3

Process vs Thread

FeatureProcessThread
DefinitionAn executing program instanceLightweight unit of a process
MemoryOwn memory spaceShares process memory
Context switchHeavy (expensive)Light (fast)
CommunicationComplex (IPC)Easy (shared memory)
Creation timeSlowFast
📌 Key PointJava supports multithreading natively — multiple threads of a single process run concurrently, improving CPU utilization and reducing execution time.

Creating Threads

Method 1: Extending Thread class

class MyThread extends Thread {
    @Override
    public void run() {                        // code that runs in new thread
        for (int i = 1; i <= 5; i++) {
            System.out.println("Thread: " + i);
        }
    }
}

MyThread t = new MyThread();
t.start(); // start() creates new thread and calls run()

Method 2: Implementing Runnable (Preferred)

class MyRunnable implements Runnable {
    @Override
    public void run() {
        for (int i = 1; i <= 5; i++)
            System.out.println(Thread.currentThread().getName() + ": " + i);
    }
}

Thread t1 = new Thread(new MyRunnable(), "Worker-1");
Thread t2 = new Thread(new MyRunnable(), "Worker-2");
t1.start();
t2.start();
📌 Key PointRunnable is preferred because Java supports only single inheritance. Implementing Runnable keeps the class free to extend another class.

Thread Lifecycle

StateDescription
NewThread object created but start() not yet called
RunnableAfter start() — ready to run, waiting for CPU
RunningScheduler picks the thread; run() is executing
Blocked / WaitingWaiting for a lock, I/O, or sleep() to expire
Terminated / Deadrun() method has completed

Thread Methods

MethodDescription
start()Creates new thread and invokes run()
run()Entry point of thread logic (don't call directly)
sleep(ms)Pauses thread for specified milliseconds
join()Waits for a thread to complete before continuing
getName()Returns thread name
setName(s)Sets thread name
getPriority()Returns priority (1–10)
setPriority(n)Sets thread priority
isAlive()Returns true if thread has not terminated
currentThread()Returns reference to currently executing thread
try {
    t1.join();  // main thread waits for t1 to finish
    Thread.sleep(500); // current thread sleeps 500ms
} catch (InterruptedException e) {
    e.printStackTrace();
}

Thread Priorities

Java thread priorities range from 1 (MIN_PRIORITY) to 10 (MAX_PRIORITY), with 5 as the default (NORM_PRIORITY). Higher priority threads are more likely to be chosen by the scheduler — but this is NOT guaranteed.

Thread t1 = new Thread(task, "High");
Thread t2 = new Thread(task, "Low");

t1.setPriority(Thread.MAX_PRIORITY); // 10
t2.setPriority(Thread.MIN_PRIORITY); // 1

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

Synchronization

When multiple threads access shared data simultaneously, data inconsistency (race condition) can occur. synchronized ensures only one thread executes a block/method at a time.

class SeatReservation {
    int availableSeats = 100;

    synchronized void book(String passenger) {
        if (availableSeats > 0) {
            availableSeats--;
            System.out.println(passenger + " booked. Remaining: " + availableSeats);
        } else {
            System.out.println("No seats for " + passenger);
        }
    }
}

SeatReservation hall = new SeatReservation();
new Thread(() -> hall.book("Ravi")).start();
new Thread(() -> hall.book("Priya")).start();
⚠️ ImportantWithout synchronization, two threads may both read availableSeats = 1, both decrement it, and the system gives 2 bookings for 1 seat — a classic race condition.

Inter-thread Communication

Threads communicate via wait(), notify(), and notifyAll() — all defined in Object class and must be called inside synchronized context.

class SharedBuffer {
    int data; boolean ready = false;

    synchronized void produce(int val) throws InterruptedException {
        while (ready) wait();   // wait if not consumed yet
        data = val; ready = true;
        System.out.println("Produced: " + val);
        notify();               // wake up consumer
    }

    synchronized int consume() throws InterruptedException {
        while (!ready) wait(); // wait until data is available
        ready = false;
        notify();               // wake up producer
        return data;
    }
}
📄

Download PDF Notes

Save these notes as a PDF for offline reference

View / Download PDF