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

Chapter 5-Threading

Uploaded by

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

Chapter 5-Threading

Uploaded by

berihufsaha12
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 9

Chapter_5: Multi-Threading concept

Multithreading in Java refers to the concurrent execution of two or more threads in a single
process to perform multiple tasks concurrently. Java provides built-in support for multithreading
through its Thread class and the Runnable interface.

Here's a basic example of creating and running a thread using the Thread class:

public class MyThread extends Thread {

public void run() {

System.out.println("MyThread is running");

public static void main(String[] args) {

MyThread thread = new MyThread();

thread.start(); // Start the thread

Alternatively, you can use the Runnable interface to create a thread:

public class MyRunnable implements Runnable {

public void run() {

System.out.println("MyRunnable is running");

public static void main(String[] args) {

MyRunnable myRunnable = new MyRunnable();

Thread thread = new Thread(myRunnable);

thread.start(); // Start the thread

}
Multithreading is commonly used in scenarios such as GUI programming, server handling
multiple client requests simultaneously, and performance optimization in CPU-bound tasks.
However, it requires careful synchronization to avoid issues like race conditions and deadlock.
Java provides synchronization mechanisms like synchronized keyword, wait(), notify(), and
notifyAll() methods to manage concurrent access to shared resources safely.

In Java, both threads and processes are mechanisms for concurrent execution, but they differ in
several key aspects:

5.1. Thread vs. process


Threads: Threads are lightweight units of execution within a single process. Multiple threads
within the same process share the same memory space, allowing them to communicate and share
data easily.

Threads are managed by the Java Virtual Machine (JVM) and are cheaper to create and manage
compared to processes.

Threads are suitable for tasks that require concurrent execution within the same application, such
as handling multiple client requests in a server application or performing background tasks while
keeping the UI responsive in a GUI application.

Processes: Processes are independent instances of a program that run in their own memory
space.

Each process has its own memory space and resources, including heap, stack, and file
descriptors.

Processes are isolated from each other, and communication between processes typically involves
more overhead, such as inter-process communication (IPC).

Creating and managing processes is more resource-intensive compared to threads. Processes are
suitable for tasks that require isolation, fault tolerance, and scalability, such as running multiple
instances of a server application on different machines or executing different programs
concurrently.

In summary, threads are lightweight units of execution within a single process and are suitable
for concurrent tasks within the same application, while processes are independent instances of a
program with their own memory space and resources, suitable for isolated and concurrent
execution of different programs or parts of a program.

Example

Sure, here are examples demonstrating both threads and processes in Java:
1. Threads Example:

public class ThreadExample extends Thread {

public void run() {

System.out.println("Thread is running");

public static void main(String[] args) {

ThreadExample thread = new ThreadExample();

thread.start(); // Start the thread

In this example, ThreadExample extends the Thread class and overrides the run() method to
define the task to be executed by the thread. The main() method creates an instance of
ThreadExample and starts the thread.

1.Process Example:

public class ProcessExample {

public static void main(String[] args) {

try {

// Start a new process

Process process = Runtime.getRuntime().exec("notepad.exe");

// Wait for the process to exit

int exitCode = process.waitFor();

// Print the exit code

System.out.println("Exit code: " + exitCode);

} catch (Exception e) {
e.printStackTrace();

In this example, the main() method starts a new process using Runtime.getRuntime().exec(),
which launches the Notepad application (notepad.exe). Then, it waits for the process to exit
using process. waitFor(), and finally prints the exit code of the process. These examples illustrate
the creation and execution of threads and processes in Java.

5.2. Multiple threads

Certainly! Here's an example of creating and running multiple threads in Java:

package javaapplication13;

public class JavaApplication13 {

public static void main(String[] args) {

// Create and start multiple threads

Thread thread1 = new MyThread("Thread 1");

Thread thread2 = new MyThread("Thread 2");

Thread thread3 = new MyThread("Thread 3");

thread1.start();

thread2.start();

thread3.start();

class MyThread extends Thread {

private String name;

public MyThread(String name) {

this.name = name;
}

public void run() {

System.out.println("Thread " + name + " is running");

In this example, we define a class MultiThreadExample with the main() method where we create
three instances of MyThread, a subclass of Thread. Each MyThread instance represents a
separate thread with a unique name. Then, we start each thread using the start() method. When
you run this program, you'll see output similar to:

Thread Thread 1 is running

Thread Thread 2 is running

Thread Thread 3 is running

This demonstrates how multiple threads can run concurrently, each executing its own run()
method independently of the others.

5.2.1. Thread priorities(Reading Assignment)


Certainly! In Java, you can set thread priorities using the setPriority() method, which accepts an
integer value ranging from 1 to 10. Threads with higher priority values are scheduled to be
executed with preference over threads with lower priority values. However, thread priorities are
only hints to the thread scheduler and might not be honored by the underlying operating
system.Here's an example demonstrating thread priorities in Java:

public class PriorityThreadExample {

public static void main(String[] args) {

Thread highPriorityThread = new MyThread("HighPriorityThread");

Thread lowPriorityThread = new MyThread("LowPriorityThread");

// Set priorities

highPriorityThread.setPriority(Thread.MAX_PRIORITY);

lowPriorityThread.setPriority(Thread.MIN_PRIORITY);
// Start threads

highPriorityThread.start();

lowPriorityThread.start();

class MyThread extends Thread {

public MyThread(String name) {

super(name);

public void run() {

System.out.println("Thread " + getName() + " priority: " + getPriority());

In this example, we create two instances of MyThread, one with high priority
(MAX_PRIORITY) and one with low priority (MIN_PRIORITY). We set the priorities using the
setPriority() method before starting the threads. Then, when the threads run, they print their
names along with their priorities.Please note that the actual behavior might vary depending on
the underlying operating system and the JVM implementation. Additionally, relying heavily on
thread priorities for application logic is generally discouraged due to platform-dependent
behavior and potential for priority inversion problems.

5.2.2. Thread synchronization (Reading Assignment)


Thread synchronization in Java is the process of coordinating the execution of multiple threads to
ensure that they access shared resources safely and avoid race conditions. Java provides several
mechanisms for thread synchronization:
1. Synchronized Methods: You can declare methods as synchronized to ensure that only one
thread can execute them at a time for an object's instance. This prevents multiple threads from
concurrently accessing critical sections of code.

public class Counter {

private int count;

public synchronized void increment() {

count++;

public synchronized int getCount() {

return count;

2. use synchronized blocks to lock specific sections of code rather than entire methods. This
allows for more fine-grained control over synchronization.

public class Counter {

private int count;

public void increment() {

synchronized (this) {

count++;

public int getCount() {

synchronized (this) {

return count;

}
}

3. Reentrant Locks: The ReentrantLock class provides an alternative to synchronized blocks. It


allows more flexible locking mechanisms and can be used with the lock() and unlock() methods.

import java.util.concurrent.locks.ReentrantLock;

public class Counter {

private int count;

private ReentrantLock lock = new ReentrantLock();

public void increment() {

lock.lock();

try {

count++;

} finally {

lock.unlock();

public int getCount() {

lock.lock();

try {

return count;

} finally {

lock.unlock();

}
}

4. Volatile Keyword: The volatile keyword ensures that changes to a variable are visible to all
threads. It prevents the compiler and CPU from reordering instructions that involve the volatile
variable.

public class SharedData {

private volatile int value;

public void setValue(int newValue) {

value = newValue;

public int getValue() {

return value;

These synchronization mechanisms help prevent issues like data corruption, race conditions, and
inconsistent state in multithreaded Java programs. It's essential to use them judiciously to ensure
thread safety and avoid deadlocks or performance bottlenecks.

You might also like