Week11 Thread
Week11 Thread
…
• Word processor, web browser, antivirus
software
Antivirus
• Multithreading
• Refers to multiple threads of control
within a single program,
Thread 1
Graphic
• Each program can run multiple threads
of control within the program, Responding Thread 2 Word
to Keystrokes Processor
CPU
• Word Processor
Grammar Thread 3
Check
Advantages of Multithreading
• Example:
• A 4-core CPU can process tasks simultaneously, such as running four different
applications at once, like web browsing, video playback, background music, and an
antivirus scan.
• A single-core CPU can only handle one of these tasks at a time, even if it switches
between them quickly.
Concurrency and Parallelism
• In a concurrent system, multiple tasks can start,
Single run, and complete in overlapping time frames, giving
Core
Time the illusion that they are running simultaneously.
Start
Task
• Concurrency is typically achieved by time-slicing
Task1.1
• CPU rapidly switches between different tasks for short periods
Task2.1
• It creates an interleaved execution pattern
Task 2.2
• Only one task is being actively worked on at any given
Task 1.2 moment.
Task 2.3 • Concurrency is useful when dealing with tasks that involve
waiting,
.
End
. • e.g. I/O operations (e.g., reading from a disk, network
. communication).
Task
• It helps to maximize resource utilization and improve responsiveness.
Concurrent
Concurrency and Parallelism
Single
Core 1 Core 2 Core1 Core2
Core
Time
Start
Task
Task1.1 Task 1.1 Task 2.2
Task2.1 Task 2.1 Task 1.2
Task 2.2 Task 2.4 Task 2.3
Task 1.2 Task1 Task 2
Task 1.3 Task 1.4
Task 2.3
.
.
Task 2.5 Task 2.6
End
.
Task
• Multi-threaded applications:
• Multi-threaded applications, such as video games or interactive simulations, use
concurrent threads to handle user inputs, physics calculations, and graphics
rendering simultaneously.
• Combining concurrency with parallel processing with multiple CPU cores for
intensive tasks (like rendering) greatly improves performance and
responsiveness.
Threading Mechanisms
• Create a thread:
MyThread thread1 = new MyThread();
• Start Execution of threads:
• Once you call start(), the code inside the run() method will be executed in a new thread of
execution, concurrently with other threads.
• The run() method is not called directly; instead, it is invoked when start() is called on a Thread
object.
thread1.start();
Example: Extending Thread class
• class MyThread extends Thread {
public void run()
{
System.out.println(" this thread is running ... ");
}
}
public class ThreadEx1 {
public static void main(String [] args ) {
The run() Method
MyThread t = new MyThread(); is invoked
t.start();
}
}
2. Threads by implementing Runnable interface
class MyThread implements Runnable{
public void run() {
// The code runs when the thread is started.
}
}
• Creating Object:
• The myObject contains the task logic defined in the run() method but does not represent a thread yet.
MyThread myObject = new MyThread();
• Creating Thread Object:
Thread thread1 = new Thread( myObject );
• Start Execution:
• This starts the thread execution by calling the start() method on the thread1 object.
• The start() method internally calls the run() method of the Runnable object myObject.
thread1.start();
Example: Threads by implementing Runnable interface
• During Life time of a thread there are many states it can enter.
• Newborn state
• Runnable state
• Running state
• Blocked state
• Dead state
Runnable
Notify() Running
•New → Runnable: When the start() method is called.
sleep() •Runnable → Running: When the thread is picked by the
wait()
scheduler. (e.g., waiting for I/O or calling the sleep() method).
•Running → Blocked/Waiting: When the thread needs to wait
Blocked for resources or a condition.
•Blocked/Waiting → Runnable: When the thread is ready to run
Idle Thread
again (e.g., the resource becomes available).
•Running → Dead: When the thread completes execution.
State Transition Diagram of a Thread
Thread Methods
• start()
• Starts a new thread.
• It causes the thread to move from the New state to the Runnable state, and the run()
method will be invoked by the JVM.
• run()
• It contains the code that is executed when the thread is started.
• It is the entry point for the thread's execution.
• You usually override this method when creating your own thread
Thread Methods
class ThreadSleep extends Thread {
• sleep(long milliseconds) public void run() {
for (int i = 1; i <= 5; i++) {
• This method pauses the try {
execution of the current thread Thread.sleep(1000); // Pauses
execution for 1 second
for the specified amount of time in } catch (InterruptedException e) {
milliseconds. System.out.println(e);
}
• It throws an InterruptedException System.out.println(i);
if the thread is interrupted while }
}
sleeping. }
public class Example_sleep {
Output:
public static void main(String[] args) {
Prints a number at every second:
System.out.println("Prints a number at
every second: ");
1
ThreadSleep t1 = new ThreadSleep();
2
t1.start();
3
}
4 }
5
class TreadJoin extends Thread {
Thread Methods public void run() {
for (int i = 1; i <= 5; i++) { Output:
try { 1
Thread.sleep(1000); 2
} catch (InterruptedException e) { 3
System.out.println(e); 4
• join() } 5
System.out.println(i); 1
• This method forces the current } 2
} 3
thread to wait until the thread on 4
}
which join() is called finishes its public class Example_Join { 5
execution. public static void main(String[] args) {
TreadJoin t1 = new TreadJoin();
• This is useful when you want to TreadJoin t2 = new TreadJoin();
ensure one thread finishes before t1.start();
try {
another starts or continues. t1.join(); Waits for t1 to finish before continuing
} catch (InterruptedException e) {
System.out.println(e);
}
t2.start();
}
}
Thread Methods class ThreadInterrupt extends Thread {
public void run() {
try {
for (int i = 1; i <= 10; i++) {
// Print the seconds
System.out.println("Second: " + i);
Thread.sleep(1000); // Sleep for 1 second between prints
• interrupt() }
System.out.println("Thread completed");
} catch (InterruptedException e) {
• It is used to interrupt a thread System.out.println("Thread interrupted");
}
that is either sleeping or }
}
waiting. public class Example_Interrupt {
public static void main(String[] args) {
• It sets the interrupt flag of the ThreadInterrupt t = new ThreadInterrupt();
t.start();
thread and can also throw an
try {
InterruptedException if the // After starting, we can interrupt the thread after a specific
thread is in a blocked/waiting time Main thread sleeps for 2 sec.
Thread.sleep(2000); // Main thread sleeps for 5 seconds
state (e.g., sleeping or t.interrupt(); Interrupt the sleeping thread
// Interrupt the thread after 5 seconds
waiting). } catch (InterruptedException e) {
Output: System.out.println(e);
Second: 1 }
}
Second: 2 }
Thread interrupted
Thread Methods class ThreadIsAlive extends Thread {
public void run() {
System.out.println("Thread is running...");
}
}
• isAlive()
public class Example_IsAlive {
• This method checks if
public static void main(String[] args) {
the thread is still ThreadIsAlive t = new ThreadIsAlive();
running or has finished t.start();
// Check if the thread is alive after starting
its execution. It returns
System.out.println("Is thread alive (before completion)? " + t.isAlive());
true if the thread is still
alive, otherwise false. try {
t.join(); // Wait for the thread to finish its task
} catch (InterruptedException e) {
e.printStackTrace();
}
• The JVM terminates itself when all user threads (non-deamon) finish
their execution.
• The JVM does not care whether Deamon thread is running or not.
• The JVM will automatically terminate any remaining daemon threads.
Thread Methods: Deamon Thread
class ThreadDeamon extends Thread {
public void run() {
if (Thread.currentThread().isDaemon()) {
• setDaemon(boolean on) System.out.println("Daemon thread running...");
} else {
• This method sets a thread as a System.out.println("User thread running...");
daemon thread. }
}
• Daemon threads are low-priority
}
threads that run in the
background and do not prevent public class Example_Deamon {
the JVM from exiting when all public static void main(String[] args) {
user threads have finished. ThreadDeamon t1 = new ThreadDeamon();
ThreadDeamon t2 = new ThreadDeamon();
t1.setDaemon(true); // Set t1 as a daemon thread
t1.start();
t2.start();
}
}
Example: Performance of Multithreading
// Task 1: Simulate downloading a file
class DownloadTask implements Runnable {
@Override
public void run() {
System.out.println("Downloading file...");
try {
Thread.sleep(2000); // Simulate time taken to download (2 seconds)
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("File download complete.");
}
}
// Task 2: Simulate processing data
class ProcessDataTask implements Runnable {
@Override
public void run() {
System.out.println("Processing data...");
try {
Thread.sleep(3000); // Simulate time taken to process data (3 seconds)
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Data processing complete.");
}
}
Example: Multithreading (cont.)
public class ThreadVsNoThreadExample {
public static void main(String[] args) {
// 1. Measure time with threads (concurrent execution)
System.out.println("Starting concurrent execution with threads...");
long startTimeWithThreads = System.nanoTime();
DownloadTask downloadTask = new DownloadTask();
ProcessDataTask processDataTask = new ProcessDataTask();
// Create threads for each task
Thread thread1 = new Thread(downloadTask);
Thread thread2 = new Thread(processDataTask);
// Start both threads to run concurrently
thread1.start();
thread2.start();
try {// Wait for both threads to finish
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
Example: Multithreading (cont.)
long endTimeWithThreads = System.nanoTime();
long timeTakenWithThreads = endTimeWithThreads - startTimeWithThreads;
System.out.println("Concurrent execution with threads completed.");
System.out.println("Time taken with threads: "+timeTakenWithThreads /1_000_000 + "
ms\n");
Downloading file...
Processing data...
Processing data...
Data processing complete.