Chapter 13: Multithreading
Introduction to Multithreading
Multiprocessing and multithreading both are used to achieve multitasking.
Multithreading allows concurrent execution of multiple parts of a program for maximum utilization of CPU.
Process vs Thread
Multiprocessing
Multithreading
Thread Advantages
Real-world Example
Word Processor:
Creating a Thread
There are two ways to create a thread in Java:
Method 1: Extending Thread Class
class MyThread extends Thread {
@Override
public void run() {
// Code that will run in separate thread
for (int i = 1; i <= 5; i++) {
System.out.println("Thread: " + Thread.currentThread().getName() +
", Count: " + i);
try {
Thread.sleep(1000); // Sleep for 1 second
} catch (InterruptedException e) {
System.out.println("Thread interrupted");
}
}
}
}
public class ThreadByExtending {
public static void main(String[] args) {
MyThread thread1 = new MyThread();
MyThread thread2 = new MyThread();
thread1.setName("Worker-1");
thread2.setName("Worker-2");
thread1.start(); // Start first thread
thread2.start(); // Start second thread
System.out.println("Main thread continues...");
}
}
Method 2: Implementing Runnable Interface
class MyRunnable implements Runnable {
@Override
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println("Runnable: " + Thread.currentThread().getName() +
", Count: " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Thread interrupted");
}
}
}
}
public class ThreadByRunnable {
public static void main(String[] args) {
MyRunnable runnable1 = new MyRunnable();
MyRunnable runnable2 = new MyRunnable();
Thread thread1 = new Thread(runnable1, "Worker-1");
Thread thread2 = new Thread(runnable2, "Worker-2");
thread1.start();
thread2.start();
System.out.println("Main thread continues...");
}
}
Extending Thread Class
Pros:
Cons:
Implementing Runnable
Pros:
Cons:
Life Cycle of a Thread
A thread goes through various states during its lifetime.
State Descriptions
1. New
Instance of thread created which is not yet started by invoking start().
Thread t = new Thread();
2. Runnable
After invocation of start() & before it is selected to be run by the scheduler.
t.start();
3. Running
After thread scheduler has selected it for execution.
// Thread is executing run() method
4. Non-Runnable (Blocked)
Thread alive, but not eligible to run due to waiting, sleeping, or blocking.
Thread.sleep(1000); // or wait(), join()
5. Terminated
run() method has exited - thread execution completed.
// Thread finished execution
The Thread Class
Below are the commonly used Constructors of Thread class:
Thread Constructors
| Constructor | Description | Example |
|---|---|---|
Thread() |
Creates a new thread with default name | Thread t = new Thread(); |
Thread(String name) |
Creates a new thread with specified name | Thread t = new Thread("MyThread"); |
Thread(Runnable r) |
Creates a new thread with Runnable target | Thread t = new Thread(runnable); |
Thread(Runnable r, String name) |
Creates a new thread with Runnable and name | Thread t = new Thread(runnable, "MyThread"); |
class TaskRunnable implements Runnable {
private String taskName;
public TaskRunnable(String taskName) {
this.taskName = taskName;
}
@Override
public void run() {
for (int i = 1; i <= 3; i++) {
System.out.println(taskName + " - Step " + i +
" [Thread: " + Thread.currentThread().getName() + "]");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Thread interrupted");
}
}
}
}
public class ThreadConstructorExample {
public static void main(String[] args) {
// Constructor 1: Thread()
Thread thread1 = new Thread() {
@Override
public void run() {
System.out.println("Anonymous thread running: " + getName());
}
};
// Constructor 2: Thread(String name)
Thread thread2 = new Thread("NamedThread") {
@Override
public void run() {
System.out.println("Named thread running: " + getName());
}
};
// Constructor 3: Thread(Runnable r)
TaskRunnable task1 = new TaskRunnable("Task1");
Thread thread3 = new Thread(task1);
// Constructor 4: Thread(Runnable r, String name)
TaskRunnable task2 = new TaskRunnable("Task2");
Thread thread4 = new Thread(task2, "CustomWorker");
// Start all threads
thread1.start();
thread2.start();
thread3.start();
thread4.start();
System.out.println("All threads started from main thread: " +
Thread.currentThread().getName());
}
}
Methods of Thread Class
Thread class offers a lot of methods such as run(), start(), join(), getPriority(), setPriority() etc.
More can be found by visiting Java docs.
Important Thread Methods
| Method | Description | Example |
|---|---|---|
start() |
Starts the thread execution | thread.start(); |
run() |
Contains the code to be executed | public void run() { ... } |
sleep(long ms) |
Pauses thread for specified milliseconds | Thread.sleep(1000); |
join() |
Waits for thread to complete | thread.join(); |
getName() |
Returns thread name | String name = thread.getName(); |
setName(String) |
Sets thread name | thread.setName("Worker"); |
getPriority() |
Returns thread priority (1-10) | int priority = thread.getPriority(); |
setPriority(int) |
Sets thread priority (1-10) | thread.setPriority(Thread.MAX_PRIORITY); |
isAlive() |
Checks if thread is alive | boolean alive = thread.isAlive(); |
currentThread() |
Returns reference to current thread | Thread current = Thread.currentThread(); |
class WorkerThread extends Thread {
public WorkerThread(String name) {
super(name);
}
@Override
public void run() {
System.out.println(getName() + " started with priority: " + getPriority());
for (int i = 1; i <= 5; i++) {
System.out.println(getName() + " - Task " + i);
try {
Thread.sleep(500); // Sleep for 500ms
} catch (InterruptedException e) {
System.out.println(getName() + " was interrupted");
return;
}
}
System.out.println(getName() + " completed");
}
}
public class ThreadMethodsExample {
public static void main(String[] args) {
System.out.println("Main thread: " + Thread.currentThread().getName());
// Create threads
WorkerThread worker1 = new WorkerThread("Worker-1");
WorkerThread worker2 = new WorkerThread("Worker-2");
WorkerThread worker3 = new WorkerThread("Worker-3");
// Set priorities
worker1.setPriority(Thread.MIN_PRIORITY); // 1
worker2.setPriority(Thread.NORM_PRIORITY); // 5
worker3.setPriority(Thread.MAX_PRIORITY); // 10
// Start threads
worker1.start();
worker2.start();
worker3.start();
// Check if threads are alive
System.out.println("Worker1 alive: " + worker1.isAlive());
System.out.println("Worker2 alive: " + worker2.isAlive());
System.out.println("Worker3 alive: " + worker3.isAlive());
try {
// Wait for all threads to complete
worker1.join();
worker2.join();
worker3.join();
} catch (InterruptedException e) {
System.out.println("Main thread interrupted");
}
System.out.println("All workers completed. Main thread ending.");
}
}
Thread Priorities
Java threads have priorities ranging from 1 to 10:
Thread.MIN_PRIORITY = 1Thread.NORM_PRIORITY = 5 (default)Thread.MAX_PRIORITY = 10Note: Thread priority is a hint to the thread scheduler. The actual behavior depends on the underlying operating system.
Practice Set
Chapter 13 - Practice Set
1. Continuous Messages
Write a program to print "Good morning" and "Welcome" continuously on the screen in Java using Threads.
2. Thread Sleep
Add a sleep method in welcome thread of question 1 to delay its execution for 200 ms.
3. Priority Methods
Demonstrate getPriority() and setPriority() methods in Java Threads.
4. Thread State
How do you get state of a given thread in Java?
5. Current Thread Reference
How do you get reference to the current thread in Java?