1. Write a program create a thread using the Runnable interface to print numbers from 1 to 5?
Algorithm :
- Start
- Class Definition (MyRunnable):
- The class MyRunnable implements the Runnable interface.
- It overrides the run() method, where a for loop prints numbers from 1 to 5.
- Main Method Starts Execution:
- Inside the main() method, an object of MyRunnable is created.
- Thread Creation:
- A new Thread object is created by passing the myRunnable object to its constructor.
- This binds the run() method of MyRunnable to the thread.
- Thread Starts Execution:
- The start() method is called on the thread.
- This causes the run() method to execute in a new thread, printing numbers 1 to 5.
- End
Program :
class MyRunnable implements Runnable { public void run() { for (int i = 1; i <= 5; i++) { System.out.println(i); } } } public class Main { public static void main(String[] args) { MyRunnable myRunnable = new MyRunnable(); Thread thread = new Thread(myRunnable); thread.start(); } } |
Output :
1 2 3 4 5 |
Explanation :
This program demonstrates how to create and run a thread in Java using the Runnable interface. The class MyRunnable implements Runnable and overrides the run() method to print numbers from 1 to 5. In the main method, an object of MyRunnable is created and passed to a new Thread object. When the start() method is called on the thread, it executes the run() method in a separate thread. This allows the task (printing numbers) to run independently from the main program thread. |
2. Write a program to demonstrate thread synchronization using synchronized keyword?
Algorithm :
- Start
- Define the Counter Class:
- A class Counter is defined with a private integer variable count initialized to 0.
- Two synchronized methods:
- increment() increases count by 1.
- getCount() returns the current value of count.
- Start of main() Method:
- A Counter object is created.
- Two threads (t1 and t2) are defined using lambda expressions.
- Each thread runs a loop from 0 to 999 and calls counter.increment() 1000 times.
- Thread Execution Begins:
- t1.start() and t2.start() begin the execution of both threads concurrently.
- Each thread starts incrementing the shared counter object.
- Wait for Threads to Finish:
- t1.join() and t2.join() ensure that the main thread waits for both t1 and t2 to complete their execution.
- Print Final Result:
- After both threads finish, the final count is retrieved using counter.getCount() and printed.
- End
Program :
class Counter { private int count = 0; public synchronized void increment() { count++; } public synchronized int getCount() { return count; } } public class Main { public static void main(String[] args) throws InterruptedException { Counter counter = new Counter(); Thread t1 = new Thread(() -> { for (int i = 0; i < 1000; i++) { counter.increment(); } }); Thread t2 = new Thread(() -> { for (int i = 0; i < 1000; i++) { counter.increment(); } }); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println(“Final count: ” + counter.getCount()); } } |
Output :
Final count: 2000 |
Explanation :
This program demonstrates safe access to a shared resource (count) in a multithreaded environment using synchronization. A Counter class is created with synchronized methods to ensure that only one thread at a time can increment the count variable. Two threads (t1 and t2) each increment the counter 1000 times. Without synchronization, race conditions could occur, resulting in incorrect final counts due to simultaneous updates. However, since the increment() method is synchronized, mutual exclusion is enforced, ensuring that all increments are properly counted. After both threads finish execution (using join() to wait), the program prints the final count, which is expected to be 2000, showing that the synchronization worked correctly. |
3. Write a program demonstrating the use of a daemon thread?
Algorithm :
- Start
- Define the Counter Class:
- A class Counter is defined with a private integer variable count initialized to 0.
- Two synchronized methods:
- increment() increases count by 1.
- getCount() returns the current value of count.
- Start of main() Method:
- A Counter object is created.
- Two threads (t1 and t2) are defined using lambda expressions.
- Each thread runs a loop from 0 to 999 and calls counter.increment() 1000 times.
- Thread Execution Begins:
- t1.start() and t2.start() begin the execution of both threads concurrently.
- Each thread starts incrementing the shared counter object.
- Wait for Threads to Finish:
- t1.join() and t2.join() ensure that the main thread waits for both t1 and t2 to complete their execution.
- Print Final Result:
- After both threads finish, the final count is retrieved using counter.getCount() and printed.
- End
Program :
class DaemonThread extends Thread { public void run() { while (true) { System.out.println(“Daemon thread is running…”); try { Thread.sleep(1000); } catch (InterruptedException e) { System.out.println(e); } } } } public class Main { public static void main(String[] args) throws InterruptedException { DaemonThread daemonThread = new DaemonThread(); daemonThread.setDaemon(true); // Setting the thread as daemon daemonThread.start(); Thread.sleep(5000); // Main thread sleeps for 5 seconds System.out.println(“Main thread ends”); } } |
Output :
Daemon thread is running… Daemon thread is running… Daemon thread is running… Daemon thread is running… Daemon thread is running… Main thread ends |
Explanation :
This program demonstrates safe access to a shared resource (count) in a multithreaded environment using synchronization. A Counter class is created with synchronized methods to ensure that only one thread at a time can increment the count variable. Two threads (t1 and t2) each increment the counter 1000 times. Without synchronization, race conditions could occur, resulting in incorrect final counts due to simultaneous updates. However, since the increment() method is synchronized, mutual exclusion is enforced, ensuring that all increments are properly counted. After both threads finish execution (using join() to wait), the program prints the final count, which is expected to be 2000, showing that the synchronization worked correctly. |
4. Write a program to implement a program to demonstrate thread communication using wait(), notify(), and notifyAll() methods?
Algorithm :
- Start
- Define the PrintOddEven Class:
- An integer number is initialized to 1.
- A lock object is used to synchronize access between two threads.
- Create the printOdd() Method:
- The method enters a synchronized block using lock.
- A while loop runs as long as number <= 10.
- If the number is even, the thread waits (lock.wait()), giving control to the even thread.
- If the number is odd, it’s printed and incremented.
- After printing, lock.notify() is called to wake up the even thread.
- Create the printEven() Method:
- Similar to printOdd(), but it checks for odd numbers to wait and even numbers to print.
- Uses the same lock object for synchronization.
- After printing the even number, it increments number and notifies the odd thread.
- main() Method Execution:
- A PrintOddEven object is created.
- Two threads are started:
- One runs printOdd()One runs printEven()
- Threads coordinate using the shared lock and wait()/notify() mechanisms.
- End
Program :
class PrintOddEven { private int number = 1; private final Object lock = new Object(); public void printOdd() { synchronized (lock) { while (number <= 10) { if (number % 2 == 0) { try { lock.wait(); // Wait until the number is odd } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(“Odd: ” + number++); lock.notify(); // Notify the even thread } } } public void printEven() { synchronized (lock) { while (number <= 10) { if (number % 2 != 0) { try { lock.wait(); // Wait until the number is even } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(“Even: ” + number++); lock.notify(); // Notify the odd thread } } } } public class Main { public static void main(String[] args) { PrintOddEven printOddEven = new PrintOddEven(); Thread oddThread = new Thread(() -> printOddEven.printOdd()); Thread evenThread = new Thread(() -> printOddEven.printEven()); oddThread.start(); evenThread.start(); } } |
Output :
Odd: 1 Even: 2 Odd: 3 Even: 4 Odd: 5 Even: 6 Odd: 7 Even: 8 Odd: 9 Even: 10 Odd: 11 |
Explanation :
This program demonstrates inter-thread communication using the wait() and notify() methods to print odd and even numbers alternately from 1 to 10. It uses a shared lock object to coordinate two threads: one that prints odd numbers and one that prints even numbers. When the odd thread sees that the number is even, it waits until notified. Similarly, the even thread waits if the number is odd. After each successful print, the thread increments the number and notifies the other to continue. This careful synchronization ensures that odd and even numbers are printed in the correct sequence without overlap or race conditions, illustrating controlled thread communication in Java. |
5. Write a program to demonstrate a deadlock situation?
Algorithm :
- Start
- Class A and B Definitions:
- Both classes A and B have synchronized methods: methodA() and methodB() respectively.
- Each of these methods tries to call the other’s last() method (which is also synchronized).
- main() Execution:
- Two objects are created: a (of class A) and b (of class B).
- Two threads are started:
- Thread t1 executes a.methodA(b)
- Thread t2 executes b.methodB(a)
- Thread t1:
- Acquires the lock on object a (due to synchronized on methodA)
- Tries to enter b.last() — needs lock on object b
- Thread t2:
- Acquires the lock on object b (due to synchronized on methodB)
- Tries to enter a.last() — needs lock on object a
- Deadlock Occurs:
- Thread t1 holds a and waits for b
- Thread t2 holds b and waits for a
- Neither thread can proceed, resulting in deadlock
- End
Program :
class A { synchronized void methodA(B b) { b.last(); } synchronized void last() {} } class B { synchronized void methodB(A a) { a.last(); } synchronized void last() {} } public class Main { public static void main(String[] args) { A a = new A(); B b = new B(); Thread t1 = new Thread(() -> a.methodA(b)); Thread t2 = new Thread(() -> b.methodB(a)); t1.start(); t2.start(); } } |
Output (Deadlock situation):
No output – threads are stuck waiting on each other forever. |
Explanation :
This program is an example of a deadlock scenario in Java. Two threads are involved, each holding a lock on a different object and trying to acquire a lock on the other. Since both threads are waiting indefinitely for the other to release the lock, neither can proceed. The deadlock happens because methodA() and methodB() are synchronized and call each other’s synchronized methods (last()), which require additional locks. This situation demonstrates the importance of careful lock ordering and synchronization design to prevent deadlocks in multithreaded programs. |
6. Write a program to demonstrate thread pooling using ExecutorService?
Algorithm :
- Start
- Task Class Definition:
- A Task class implements Runnable.
- It takes a taskId through the constructor.
- The run() method prints the task ID and the name of the thread executing it.
- Main Class Execution Begins:
- The main() method creates a FixedThreadPool of 3 threads using Executors.newFixedThreadPool(3).
- This means only 3 threads will run concurrently, even if more tasks are submitted.
- Submitting Tasks:
- A loop runs from 1 to 5 and submits five Task instances to the executor.
- The executor.submit(new Task(i)) adds the task to the pool’s work queue.
- Task Execution:
- The thread pool picks up available tasks and assigns them to the 3 available threads.
- Tasks 1–3 may start immediately (depending on thread availability), while Tasks 4 and 5 wait until a thread becomes free.
- Shutdown Executor:
- After all tasks are submitted, executor.shutdown() is called to stop accepting new tasks and finish existing ones.
- End
Program :
class Task implements Runnable { private final int taskId; public Task(int taskId) { this.taskId = taskId; } public void run() { System.out.println(“Task ” + taskId + ” is executed by ” + Thread.currentThread().getName()); } } import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class Main { public static void main(String[] args) { ExecutorService executor = Executors.newFixedThreadPool(3); for (int i = 1; i <= 5; i++) { executor.submit(new Task(i)); // Submit 5 tasks to the thread pool } executor.shutdown(); // Shutdown the executor } } |
Output :
Task 1 is executed by pool-1-thread-1 Task 2 is executed by pool-1-thread-3 Task 3 is executed by pool-1-thread-2 Task 4 is executed by pool-1-thread-1 Task 5 is executed by pool-1-thread-3 |
Explanation :
This Java program utilizes the ExecutorService framework to manage concurrent execution of tasks with a fixed number of threads. It creates five tasks but only three threads using Executors.newFixedThreadPool(3), which means only three tasks can run at the same time. The rest are queued until threads become available. Each Task prints its ID and the thread name, showing which thread handled which task. This approach provides a more efficient and scalable way to manage threads compared to creating individual threads manually, especially when dealing with large numbers of tasks. |
7. Write a program to demonstrate the use of the Thread.sleep() method, where two threads print numbers with a delay?
Algorithm :
- Start
- Class Definition (PrintNumbers):
- Implements the Runnable interface.
- The run() method contains a loop from 1 to 5.
- Inside the loop, it sleeps for 1 second (Thread.sleep(1000)) and then prints the current number.
- Main Method Execution:
- An object of PrintNumbers is created.
- Two Thread objects (thread1 and thread2) are created using the same printNumbers instance.
- Both threads are started using start().
- Thread Execution:
- thread1 and thread2 begin executing concurrently.
- Since both use the same Runnable instance, they execute the same run() method at the same time.
- Output from both threads may interleave depending on the thread scheduler.
- End
Program :
class PrintNumbers implements Runnable { public void run() { for (int i = 1; i <= 5; i++) { try { Thread.sleep(1000); // Sleep for 1 second System.out.println(i); } catch (InterruptedException e) { e.printStackTrace(); } } } } public class Main { public static void main(String[] args) { PrintNumbers printNumbers = new PrintNumbers(); Thread thread1 = new Thread(printNumbers); Thread thread2 = new Thread(printNumbers); thread1.start(); thread2.start(); } } |
Output :
1 1 2 2 3 3 4 4 5 5 |
Explanation :
This Java program creates two threads that run the same task defined in the PrintNumbers class. Each thread prints numbers from 1 to 5 with a delay of 1 second between each print. Because both threads are started almost simultaneously and share the same Runnable instance, they execute concurrently and independently of each other. This results in interleaved output, where numbers from both threads may appear in an unpredictable order. It showcases basic concurrent execution and the effect of thread scheduling in Java. |
8. Write a program to create a thread by extending the Thread class to print even numbers from 2 to 10?
Algorithm :
- Start
- Define the EvenNumbers Class:
- It extends Thread.
- The run() method contains a for loop that prints even numbers from 2 to 10.
- Inside the main() Method:
- An instance of EvenNumbers is created.
- The start() method is called on the instance, which internally calls the run() method in a separate thread.
- Thread Execution:
- The run() method executes independently, printing the even numbers.
- End
Program :
class EvenNumbers extends Thread { public void run() { for (int i = 2; i <= 10; i += 2) { System.out.println(i); } } } public class Main { public static void main(String[] args) { EvenNumbers evenThread = new EvenNumbers(); evenThread.start(); } } |
Output :
2 4 6 8 10 |
Explanation :
In this program, the EvenNumbers class extends the Thread class and overrides the run() method to print even numbers from 2 to 10. In the main method, an object of EvenNumbers is created and its start() method is invoked. This starts a new thread of execution, separate from the main thread, which runs the run() method. This program is a simple illustration of creating and starting a thread in Java using the Thread class. |
9. Write a program where the main thread waits for two threads to complete before it terminates?
Algorithm :
- Start
- Define Task1 and Task2 Classes:
- Both extend the Thread class.
- Each overrides the run() method and uses Thread.sleep() to simulate time-consuming tasks:
- Task1 sleeps for 2 seconds.
- Task2 sleeps for 3 seconds.
- In the main() Method:
- Instances of Task1 and Task2 are created and started with start().
- task1.join() is called, making the main thread wait for Task1 to finish.
- task2.join() is called next, making the main thread wait for Task2 to finish.
- Once both threads complete, the message “Main thread ends after task completion” is printed.
- End
Program :
class Task1 extends Thread { public void run() { try { Thread.sleep(2000); // Simulate task with 2 seconds sleep System.out.println(“Task 1 completed”); } catch (InterruptedException e) { e.printStackTrace(); } } } class Task2 extends Thread { public void run() { try { Thread.sleep(3000); // Simulate task with 3 seconds sleep System.out.println(“Task 2 completed”); } catch (InterruptedException e) { e.printStackTrace(); } } } public class Main { public static void main(String[] args) throws InterruptedException { Task1 task1 = new Task1(); Task2 task2 = new Task2(); task1.start(); task2.start(); task1.join(); // Wait for Task1 to finish task2.join(); // Wait for Task2 to finish System.out.println(“Main thread ends after task completion”); } } |
Output :
Task 1 completed Task 2 completed Main thread ends after task completion |
Explanation :
This Java program uses two threads, Task1 and Task2, each simulating a delay using Thread.sleep() to represent task execution. The main thread starts both tasks concurrently using start(). It then calls join() on each thread, causing it to pause and wait until both threads complete their execution. This ensures that the final message from the main thread only prints after both tasks are done. The use of join() is critical in scenarios where the main thread must wait for background threads to finish before terminating or proceeding with further logic. |
10. Write a program to demonstrate how to interrupt a thread?
- Start
- Define the InterruptTask class:
- Extends Thread and overrides the run() method.
- Runs a loop from 1 to 10:
- Checks if the thread was interrupted using Thread.interrupted(). If true, it prints a message and breaks the loop.
- Otherwise, it prints the number and sleeps for 1 second.
- If InterruptedException is caught during sleep(), it prints a message and breaks the loop.
- In the main() method:
- A thread of InterruptTask is created and started.
- Main thread sleeps for 3 seconds using Thread.sleep(3000).
- After 3 seconds, it interrupts the running thread using thread.interrupt().
- End
Program :
class InterruptTask extends Thread { public void run() { for (int i = 1; i <= 10; i++) { if (Thread.interrupted()) { System.out.println(“Thread interrupted”); break; } System.out.println(i); try { Thread.sleep(1000); } catch (InterruptedException e) { System.out.println(“Thread interrupted during sleep”); break; } } } } public class Main { public static void main(String[] args) throws InterruptedException { InterruptTask thread = new InterruptTask(); thread.start(); // Interrupt the thread after 3 seconds Thread.sleep(3000); thread.interrupt(); } } |
Output :
1 2 3 Thread interrupted during sleep |
Explanation :
The program creates a thread that prints numbers from 1 to 10, sleeping for 1 second between each print. Meanwhile, the main thread pauses for 3 seconds before calling interrupt() on the child thread. This interruption may either be detected immediately using Thread.interrupted() or while the thread is sleeping, in which case it throws an InterruptedException. In both scenarios, the thread handles the interruption gracefully by printing a message and exiting the loop, thus stopping its execution early. This example is useful for understanding how to safely stop a thread in Java. |
11. Write a program where two threads print odd and even numbers alternately?
Algorithm :
- Start
- Shared Resource Initialization:
- number starts at 1.
- A common lock object (lock) is used for synchronization.
- Odd Thread (printOdd() method):
- Acquires lock and enters the while loop (while number <= 10).
- If the number is even, it calls lock.wait() to wait.
- If odd, it prints the number, increments it, and calls lock.notify() to wake up the even thread.
- Even Thread (printEven() method):
- Also synchronized on the same lock.
- If the number is odd, it waits.
- If even, it prints the number, increments it, and notifies the odd thread.
- Main Method:
- Creates and starts both threads.
- End
Program :
class OddEvenPrinter { private int number = 1; private final Object lock = new Object(); public void printOdd() { synchronized (lock) { while (number <= 10) { if (number % 2 == 0) { try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(“Odd: ” + number++); lock.notify(); } } } public void printEven() { synchronized (lock) { while (number <= 10) { if (number % 2 != 0) { try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(“Even: ” + number++); lock.notify(); } } } } public class Main { public static void main(String[] args) { OddEvenPrinter oddEvenPrinter = new OddEvenPrinter(); Thread oddThread = new Thread(() -> oddEvenPrinter.printOdd()); Thread evenThread = new Thread(() -> oddEvenPrinter.printEven()); oddThread.start(); evenThread.start(); } } |
Output :
Odd: 1 Even: 2 Odd: 3 Even: 4 Odd: 5 Even: 6 Odd: 7 Even: 8 Odd: 9 Even: 10 Odd: 11 |
Explanation :
The program ensures that two threads — one printing odd numbers and the other printing even numbers — coordinate their execution without interference. They share a common counter (number) and synchronize on a common lock object. The odd-printing thread proceeds only when the number is odd, and the even-printing thread when the number is even. When one thread finishes its turn, it notifies the other using lock.notify() and waits using lock.wait() if it’s not their turn. This interplay continues until the number exceeds 10. This is a classic example of inter-thread communication in Java using wait()/notify() for coordinated task execution. |
12. Write a program to create a thread group and execute multiple threads in the same group?
Algorithm :
- Start
- Define a Thread Class:
- MyTask extends Thread and overrides the run() method to print the current thread’s name.
- Create a ThreadGroup:
- A thread group named “MyThreadGroup” is created in the main method.
- Create Threads in the Group:
- Three instances of MyTask are created (task1, task2, task3) and associated with the group.
- Start Threads:
- Each thread is started using start(), causing the run() method to execute concurrently.
- End
Program :
class MyTask extends Thread { public MyTask(ThreadGroup group, String name) { super(group, name); } public void run() { System.out.println(Thread.currentThread().getName() + ” is executing”); } } public class Main { public static void main(String[] args) { ThreadGroup group = new ThreadGroup(“MyThreadGroup”); MyTask task1 = new MyTask(group, “Thread-1”); MyTask task2 = new MyTask(group, “Thread-2”); MyTask task3 = new MyTask(group, “Thread-3”); task1.start(); task2.start(); task3.start(); } } |
Output :
Thread-1 is executing Thread-2 is executing Thread-3 is executing |
Explanation :
This program illustrates how Java’s ThreadGroup class can be used to logically group multiple threads under one umbrella. Each thread is an instance of MyTask, which prints its name when executed. These threads are all assigned to the same ThreadGroup, “MyThreadGroup”, during their construction. This setup can be useful for managing threads collectively — for example, to set priorities, interrupt all threads in the group, or monitor their status. While ThreadGroup is less commonly used in modern Java (with ExecutorService being preferred), it still serves as a useful educational and legacy feature. |
13. Write a program to create a countdown timer that prints numbers from 10 to 1 using a thread?
Algorithm :
- Start
- Create CountdownTimer class extending Thread.
- Override the run() method:
- Loop from 10 down to 1.
- In each iteration:
- Print the number.
- Call Thread.sleep(1000) to pause for 1 second.
- Catch and handle InterruptedException.
- After the loop, print “Countdown Finished!”.
- In Main, create an instance of CountdownTimer and call start() to run the countdown in a new thread.
- End
Program :
class CountdownTimer extends Thread { public void run() { for (int i = 10; i > 0; i–) { System.out.println(i); try { Thread.sleep(1000); // Sleep for 1 second } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(“Countdown Finished!”); } } public class Main { public static void main(String[] args) { CountdownTimer countdown = new CountdownTimer(); countdown.start(); } } |
Output :
10 9 8 7 6 5 4 3 2 1 Countdown Finished! |
Explanation :
The program defines a thread class CountdownTimer that overrides the run() method to perform a countdown. Using a for loop, it prints numbers from 10 to 1, sleeping for one second between each to simulate a timer. The sleep() method is used to delay execution, and any InterruptedException is caught and handled with e.printStackTrace(). The main() method starts the countdown by creating a thread instance and calling start(), which executes the run() method in a new thread, allowing other parts of the program (if any) to continue running concurrently. |
14. Write a program to use a CyclicBarrier to synchronize multiple threads, where each thread performs a task before proceeding?
Algorithm :
- Start
- Constructor takes a taskId and a CyclicBarrier object.
- In the run() method:
- Print a message indicating the task is doing some work.
- Call barrier.await() to wait for all threads to reach the barrier.
- Once all threads reach the barrier, print a continuation message.
- In the Main class:
- Set numberOfThreads = 3.
- Create a CyclicBarrier for 3 parties and provide a barrier action (a Runnable that prints a message once all threads arrive).
- Start 3 threads, each executing a Task.
- End
Program :
import java.util.concurrent.*; class Task implements Runnable { private final int taskId; private final CyclicBarrier barrier; public Task(int taskId, CyclicBarrier barrier) { this.taskId = taskId; this.barrier = barrier; } public void run() { try { System.out.println(“Task ” + taskId + ” is performing some work.”); barrier.await(); // Wait for other threads to reach the barrier System.out.println(“Task ” + taskId + ” is continuing after barrier.”); } catch (InterruptedException | BrokenBarrierException e) { e.printStackTrace(); } } } public class Main { public static void main(String[] args) throws InterruptedException { int numberOfThreads = 3; CyclicBarrier barrier = new CyclicBarrier(numberOfThreads, () -> System.out.println(“All tasks reached the barrier, now continuing…”)); for (int i = 1; i <= numberOfThreads; i++) { new Thread(new Task(i, barrier)).start(); } } } |
Output :
Task 3 is performing some work. Task 2 is performing some work. Task 1 is performing some work. All tasks reached the barrier, now continuing… Task 1 is continuing after barrier. Task 3 is continuing after barrier. Task 2 is continuing after barrier. |
Explanation :
This program uses CyclicBarrier to synchronize three threads so they pause at a certain point and wait for each other before moving forward. Each Task simulates doing some work, then calls barrier.await(), pausing until all three threads reach this point. Once they do, a predefined action prints a message: “All tasks reached the barrier, now continuing…”. Then, each task continues its execution. This is a classic use case for CyclicBarrier—helpful in parallel computations or multi-stage processing where threads must align at common checkpoints. |