Main Components of the Concurrency Utilities - 4 - Phaser
Start course
Difficulty
Intermediate
Duration
2h
Students
16
Description

In this course, we will learn the concepts of Java EE 7 with a focus on Concurrency Utilities with Threads, Semaphore, Phaser and other methods, and Transactions.

Learning Objectives

  • Concurrency Utilities 

Intended Audience

  • Anyone looking to get Oracle Java Certification
  • Those who want to improve Java 7 EE knowledge
  • Java developers

Prerequisites

  • Have at least 2 years of Java development experience 
Transcript

Hello there. In this lesson, we will continue to talk about concurrency in java. So, let's start. Phaser. Phaser is a useful feature when few independent threads have to work in phases to complete a task. So, a synchronization point is needed for the threads to work on a part of a task, wait for others to complete other parts of the task,  and do a sync up before advancing to complete the next part of the task. Phaser creates a  Phaser object with no registered parties and no parents. The initial phase is set to zero. int register() adds a new thread/party to this  Phaser object, returns the phase current number, throws an illegal state exception if the maximum supported parties are already registered. int bulkRegister() adds num threads of unarrived parties to this  Phaser object, returns the phase current number, throws an illegal state exception if maximum supported parties are already registered. int arrive () arrives at this phase without waiting for other threads to arrive, returns the arrival phase number, can throw an illegal state exception. int arriveAndDeregister(); same as the previous method, but also deregisters from the  Phaser object.

int arriveAndWaitAdvance() arrive at this phase and wait, i.e., blocks until other threads arrive. int awaitAdvance() waits, i.e., blocks until this  Phaser object advances to the given phase value. int getRegisteredParties() returns the number of threads/parties registered with this  Phaser object. int getArrivedParties() returns the number of threads/parties arrived at the current phase of the  Phaser object. int getUnarrivedParties() returns the number of threads/parties that have not arrived when compared to the registered parties at the current phase of the  Phaser object. Consider the example of processing a delivery order in a small coffee shop. Assume that there are only three workers; a cook, a helper, and an attendant. To simplify the program logic, assume that each delivery order consists of three food items. Completing a delivery order consists of preparing the three orders one after another. To complete preparing a food item, all three workers, the cook, the helper, and the attendant should do their part of the work. Here, this example shows how this situation can be implemented using the Phaser class.

Let's move on to the Eclipse. We'll create a Java class in this project. Right click to show the context menu and choose the menu item new and class. We must specify the class name. And lastly, I will check the box public static void main to let Eclipse create the main() method. Process order thread is the master thread overlooking to make sure that the cook, helper, and attendant are doing their part of the work to complete preparing the food items and to complete order delivery. To simplify the logic, we assume that each delivery order consists of exactly three food items. The  Phaser is the synchronizer to make food items one by one and deliver it before moving to the next item. Prepare mix and deliver this food item. 

Work completed for this delivery order. So, deregister. The work could be a cook, helper or attendant. Though the three work independently, they should all synchronize their work together to do their part and complete preparing a food item. Work completed for this delivery order. So, deregister. Simulate time for preparing the food item. As you can see, the compiler gives a compilation error because we have to put it in the try and catch block.

Here, I choose the surround with try/catch option. As you can see, the compilation error has disappeared. Now, let's run the application and test it. The output will be like this. In this program, you create a  Phaser object to support the synchronizing of three worker thread objects. You create a  Phaser object by calling the default constructor of the  Phaser object. When the worker thread objects are created, they register themselves to the  Phaser object. In this case, you would not need to call the register() method on the  Phaser object in the worker thread constructor. In this case, you've assumed that a delivery order consists of processing three food items. So, the four loop runs three times. 

For each iteration, you call delivery_order.arriveAndAwaitAdvance(). For this second statement to proceed, all the three parties have to complete their part of the work to prepare the food item. You simulate preparing food by calling the sleep() method in the run() method  for these worker threads. These worker threads call  delivery_order.arriveAndAwaitAdvance()  for preparing each food item. As each food item is prepared, the work progresses to the next phase. Once three phases are complete, the delivery order processing is complete and the program returns. So, that's it. Hope to see you in our next lesson. Have a nice day.

 

About the Author
Students
1985
Courses
64
Learning Paths
4

OAK Academy is made up of tech experts who have been in the sector for years and years and are deeply rooted in the tech world. They specialize in critical areas like cybersecurity, coding, IT, game development, app monetization, and mobile development.

Covered Topics