INSTITUT D’ENSEIGNEMENT SUPÉRIEUR DE RUHENGERI
B.P. 155, Ruhengeri, Rwanda
T : +250 788 90 30 30, +250 788 90 30 32,W : www.ines.ac.rw, E :
[email protected] FACULTY OF SCIENCES AND INFORMATON
TECHNOLOGY
DEPARTMENT OF COMPUTER SCIENCE
Advanced Java Programming
- Multithreading & Concurrency -
by:
Clement Munyentwari
DEFINITIONS
● Multithreading:
○ The ability of a CPU or a single core in a multi-
core processor to execute multiple threads
concurrently, allowing multiple operations to run
in parallel.
● Concurrency:
○ The execution of multiple sequences of
operations at the same time.
○ Dealing with multiple tasks at once, either by
time-slicing on a single processor or in parallel
on multiple processors.
IMPORTANCE
● Multithreading and concurrency are critical for
improving the efficiency and performance of Java
applications, especially in systems with multiple
cores.
● They allow better utilization of CPU resources,
smoother user interfaces, and quicker processing of
large tasks.
MULTITHREADING CONCEPTS
● Threads
○ A thread is a lightweight process;
○ The smallest unit of execution in a program.
○ In Java, a thread can be created by extending the Thread
class or implementing the Runnable interface.
● Life Cycle of a Thread
○ New: The thread is created but not yet started.
○ Runnable: The thread is ready to run but waiting for CPU
time.
○ Running: The thread is actively executing.
○ Blocked: The thread is blocked and waiting for some
condition.
○ Terminated: The thread has completed its execution.
MULTITHREADING CONCEPTS
● Thread Priority
○ Threads can have priorities (ranging from 1 to 10 in Java).
Higher priority threads are more likely to be executed
first, though this is not guaranteed.
● Synchronization
○ Synchronization is a technique to control access to shared
resources by multiple threads to prevent inconsistency.
○ Java provides synchronized blocks and methods to ensure
that only one thread can access the resource at a time.
● Inter-Thread Communication
○ Threads can communicate with each other using methods
like wait(), notify(), and notifyAll() which are used to
coordinate access to shared resources.
EXAMPLE#1
1. Creating a Thread by public class TestThread {
Extending the Thread Class public static void
● Solution: main(String[] args) {
class MyThread extends Thread MyThread t1 = new
{ MyThread();
public void run() { MyThread t2 = new
for (int i = 1; i <= 5; i++) { MyThread();
System.out.println(i + " - " + t1.start();
Thread.currentThread().getNa t2.start();
me()); }
} }
}
}
EXAMPLE#2
2. Creating a Thread by
Implementing Runnable public class TestRunnable {
Interface public static void
● Solution: main(String[] args) {
class MyRunnable implements Thread t1 = new
Runnable { Thread(new MyRunnable());
public void run() { Thread t2 = new
for (int i = 1; i <= 5; i++) { Thread(new MyRunnable());
System.out.println(i + " - " + t1.start();
Thread.currentThread().getNa t2.start();
me()); }
} }
}
CONCURRENCY
● Executors Framework
○ The Executors framework provides a higher-level
replacement for working with threads directly.
○ It provides thread pools and manages thread lifecycle
efficiently.
● Callable and Future
○ Callable is similar to Runnable, but it can return a result and
throw a checked exception.
○ Future is used to represent the result of an asynchronous
computation.
● Synchronizers
○ Java provides synchronizer classes like CountDownLatch,
CyclicBarrier, Semaphore, and Exchanger to manage
complex thread interactions.
EXERCISES
● Thread Synchronization:
○ Write a Java program where two threads access a shared
resource. Use synchronization to ensure the consistency of
the resource.
■ Answer:
Final count: 2000
● Using Executors:
○ Create a Java program that uses the Executors
framework to run a series of tasks concurrently. Use
Callable to return results and handle exceptions.
■ Answer:
Result of task1: 1
Result of task2: 2