0% found this document useful (0 votes)
9 views9 pages

Unit 02 Multithreading Threads in Java

In Java, a thread is a lightweight subprocess that allows for multithreading, enabling multiple tasks to run concurrently. Java provides built-in support for threads through the Thread class and Runnable interface, with various methods for synchronization and inter-thread communication. Key concepts include thread life cycle states, thread priorities, and the importance of synchronization to prevent data inconsistency.

Uploaded by

v6jnhhy8d8
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
9 views9 pages

Unit 02 Multithreading Threads in Java

In Java, a thread is a lightweight subprocess that allows for multithreading, enabling multiple tasks to run concurrently. Java provides built-in support for threads through the Thread class and Runnable interface, with various methods for synchronization and inter-thread communication. Key concepts include thread life cycle states, thread priorities, and the importance of synchronization to prevent data inconsistency.

Uploaded by

v6jnhhy8d8
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

What Are Threads in Java?

In Java, a thread is a lightweight subprocess — the smallest unit of execution. It allows a


program to perform multiple tasks simultaneously, also known as multithreading.

Java provides built-in support for threads via the [Link] class and the Runnable
interface.

Key Concepts

Term Explanation
Thread An independent path of execution in a program.
Multithreading Running two or more threads concurrently.
Main Thread The first thread started when a Java program begins.
Concurrency Ability to execute multiple tasks seemingly at the same time.

Real-World Analogy

Imagine you're cooking while listening to music.

 Cooking = one thread


 Music = another thread
These tasks are happening simultaneously, much like Java threads.

Java Thread Example

Using Thread Class:

classMyThread extends Thread {


public void run() {
for (inti = 1; i<= 5; i++) {
[Link]("Running Thread: " + i);
}
}

public static void main(String[] args) {


MyThread t1 = new MyThread();
[Link](); // starts a new thread
for (inti = 1; i<= 5; i++) {
[Link]("Main Thread: " + i);
}
}
}

Output (varies per run):

Main Thread: 1
Running Thread: 1
Main Thread: 2
Running Thread: 2
...
Notice: Both threads run independently and their outputs may interleave.

Real-World Use Cases

Scenario Thread Use


Web server handling many clients Each client can be handled by a thread
File downloading while typing Background thread downloads file
Games Separate threads for UI, logic, and audio
Banking software Threads for transactions, alerts, etc.

Life Cycle of a Thread in Java

A thread in Java goes through several stages during its lifetime. These stages make up the
thread life cycle.

Thread Life Cycle States

State Description

New Thread is created but not yet started.

Runnable Thread is ready to run and waiting for CPU time.

Running Thread is currently executing.

Blocked Thread is waiting for a monitor lock (e.g., another thread holds the lock).

Waiting Thread is waiting indefinitely for another thread to perform a task.

Timed Waiting Thread is waiting for a specified time.

Terminated (Dead) Thread has completed execution or has been stopped.


Thread Life Cycle Diagram

Java Example: Thread Lifecycle Demonstration


classDemoThread extends Thread {
public void run() {
[Link]("Thread is running...");
try {
[Link](1000); // Timed waiting state
} catch (InterruptedException e) {
[Link]("Thread interrupted");
}
[Link]("Thread finished.");
}

public static void main(String[] args) {


DemoThread t = new DemoThread(); // New state
[Link]("Thread state after creation: " + [Link]());

[Link](); // Runnable state


[Link]("Thread state after start: " + [Link]());

try {
[Link](200); // Give time for t to enter sleep (timed waiting)
[Link]("Thread state during sleep: " + [Link]());
[Link](); // Wait for thread to die
} catch (InterruptedException e) {
[Link]();
}

[Link]("Thread state after completion: " + [Link]()); //


Terminated
}
}
Output (sample):
Thread state after creation: NEW
Thread state after start: RUNNABLE
Thread is running...
Thread state during sleep: TIMED_WAITING
Thread finished.
Thread state after completion: TERMINATED

In Java, you can create threads using two primary approaches:

1. Extending the Thread class


classMyThread extends Thread {
public void run() {
[Link]("Thread running using Thread class.");
}

public static void main(String[] args) {


MyThread t1 = new MyThread(); // Create thread object
[Link](); // Start thread
}
}

run() contains the code that the thread executes.


start() creates a new thread and calls run() internally.

2. Implementing the Runnable interface


classMyRunnable implements Runnable {
public void run() {
[Link]("Thread running using Runnable interface.");
}

public static void main(String[] args) {


MyRunnablemyRunnable = new MyRunnable();
Thread t1 = new Thread(myRunnable); // Pass runnable to Thread
[Link](); // Start thread
}
}

Recommended when your class extends another class (since Java doesn't support multiple
inheritance).

3. Using Lambda Expression (Java 8+)


public class LambdaThread {
public static void main(String[] args) {
Thread t = new Thread(() -> {
[Link]("Thread running using lambda expression.");
});
[Link]();
}
}

Short and clean for simple tasks.


Comparison

Approach Use When

Extending Thread You don't need to extend another class

Implementing Runnable You want to separate task logic from thread class

Lambda expression You want concise syntax for simple runnable logic

Thread Priorities in Java

In Java, every thread has a priority that helps the Thread Scheduler decide the order in
which threads should be executed.

Priority Range

Constant Value Description


Thread.MIN_PRIORITY 1 Lowest priority
Thread.NORM_PRIORITY 5 Default priority
Thread.MAX_PRIORITY 10 Highest priority

Default priority is 5 (NORM_PRIORITY).

How Priorities Work

 Higher-priority threads are more likely to be scheduled before lower-priority threads.


 But thread scheduling is JVM and OS dependent – priority is a hint, not a
guarantee.

Example Program
public class ThreadPriorityExample {
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
[Link]("Thread 1 running...");
});

Thread t2 = new Thread(() -> {


[Link]("Thread 2 running...");
});

Thread t3 = new Thread(() -> {


[Link]("Thread 3 running...");
});

// Set priorities
[Link](Thread.MIN_PRIORITY); // Priority 1
[Link](Thread.NORM_PRIORITY); // Priority 5
[Link](Thread.MAX_PRIORITY); // Priority 10

// Start threads
[Link]();
[Link]();
[Link]();
}
}

Output (may vary):


Thread 3 running...
Thread 2 running...
Thread 1 running...

Output may differ on different systems, as priority does not enforce strict order.

When to Use Priorities

 When some threads are more critical than others (e.g., UI vs background logging).
 For fine-tuning performance, but never rely on it for correctness.

Synchronization of Threads in Java

Synchronization in Java is a mechanism to control access to shared resources by multiple


threads. It prevents race conditions, where two or more threads try to modify the same
resource simultaneously.

Why Synchronization is Needed?

If two threads access the same variable or object at the same time, it can lead to data
inconsistency.

How Java Provides Synchronization

Java uses the synchronized keyword to:

 Make a method synchronized.


 Make a block of code synchronized (within a method).

Example Without Synchronization (Problematic)


class Counter {
int count = 0;
public void increment() {
count++;
}
}

public class UnsynchronizedDemo {


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

Thread t1 = new Thread(() -> {


for(inti = 0; i< 1000; i++) [Link]();
});

Thread t2 = new Thread(() -> {


for(inti = 0; i< 1000; i++) [Link]();
});

[Link]();
[Link]();
[Link]();
[Link]();

[Link]("Final count (expected 2000): " + [Link]);


}
}

Output may be less than 2000 because threads overwrite each other.

Example With Synchronization (Corrected)


class Counter {
int count = 0;

public synchronized void increment() {


count++;
}
}

public class SynchronizedDemo {


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

Thread t1 = new Thread(() -> {


for(inti = 0; i< 1000; i++) [Link]();
});

Thread t2 = new Thread(() -> {


for(inti = 0; i< 1000; i++) [Link]();
});

[Link]();
[Link]();
[Link]();
[Link]();

[Link]("Final count (expected 2000): " + [Link]);


}
}
Output will always be 2000, thanks to synchronized.

Synchronization Types

Type Usage
Synchronized Method Synchronizes the whole method
Synchronized Block Synchronizes only a critical part
Static Synchronization Synchronizes static methods

Inter-Thread Communication in Java

Inter-thread communication in Java allows multiple threads to communicate and


coordinate with each other using wait-notify mechanisms. It is often used in producer-
consumer problems where threads share a common resource.

Key Methods (Defined in Object class)

Method Description
wait()
Causes the current thread to wait until another thread calls notify() or
notifyAll() on the same object.
notify() Wakes up one thread waiting on the object's monitor.
notifyAll() Wakes up all threads waiting on the object's monitor.

These methods must be called inside a synchronized block or method.

Simple Example: Inter-thread Communication


classSharedResource {
boolean flag = false;

// Producer
synchronized void produce() {
try {
if (flag) wait(); // wait if already produced
[Link]("Producing...");
flag = true;
notify(); // notify consumer
} catch (InterruptedException e) {
[Link]();
}
}

// Consumer
synchronized void consume() {
try {
if (!flag) wait(); // wait if nothing to consume
[Link]("Consuming...");
flag = false;
notify(); // notify producer
} catch (InterruptedException e) {
[Link]();
}
}
}

public class InterThreadExample {


public static void main(String[] args) {
SharedResource res = new SharedResource();

// Producer thread
Thread producer = new Thread(() -> {
for (inti = 0; i< 5; i++) {
[Link]();
}
});

// Consumer thread
Thread consumer = new Thread(() -> {
for (inti = 0; i< 5; i++) {
[Link]();
}
});

[Link]();
[Link]();
}
}

Output:
Producing...
Consuming...
Producing...
Consuming...
...

Important Notes

 Always use wait(), notify(), notifyAll() within a synchronized context.


 Otherwise, you'll get IllegalMonitorStateException.

You might also like