"Hi, Amigo!"
"Today you'll start working on a super state-of-the-art and useful program! It's an electronic menu. Take a look:"
"Far out! What's it for?"
"You ask so many questions! Look, you do it, and then we'll talk. Consult with the secret agent. He'll give you all the necessary instructions."
"Captain, sir! I can't create such beautiful artwork!"
"Remember, you need to implement the necessary business logic. The pictures will be created by a designer. Go see the secret agent. You'll figure it out along the way."
"I'll figure it out, sir!"
16
Task
Java Multithreading,
level 9,
lesson 15
Locked
Restaurant (part 1)
Let's write a program to automate what happens in a restaurant.
We'll state the task like this: the restaurant manager wants the following:
1) each table has a tablet that can be used to place orders;
2) while an order is being prepared, the tablet shows ads.
32
Task
Java Multithreading,
level 9,
lesson 15
Locked
Restaurant (part 2)
1. We work with the console a lot. It's time to create a single point of interaction.
Create a ConsoleHelper class with a single BufferedReader, through which we will work with the console.
Remember, this class does not store any data or state, so all its methods will be static.
32
Task
Java Multithreading,
level 9,
lesson 15
Locked
Restaurant (part 3)
Now we can create orders. Let's make it so they are automatically sent to the cook.
There are many different ways to implement this functionality.
Read about the Observer pattern at http://en.wikipedia.org/wiki/Observer_pattern
It's already implemented in Java, and we're going to use it.
16
Task
Java Multithreading,
level 9,
lesson 15
Locked
Restaurant (part 4)
What do we have? The cook has prepared the dishes. It's time to take them away, but the waiter is unaware.
We need to notify the waiter that it's time to pick up the order from the kitchen.
This situation is similar to the previous task, so we'll use the Observer pattern again.
16
Task
Java Multithreading,
level 9,
lesson 15
Locked
Restaurant (part 5)
The cook currently prepares dishes instantaneously. In reality, cooking takes some time.
We need to calculate the time required to prepare the entire order, so we can then select commercials to fill the time.
1. Suppose we know the cooking time for each dish in minutes.
16
Task
Java Multithreading,
level 9,
lesson 15
Locked
Restaurant (part 6)
An order is created, prepared by the cook, and then carried out to the guest. We also calculate the time required to fill the order.
We'll consider the first part of the task complete.
Let's move on to the second: while the order is being prepared, ads should be shown on the tablet.
16
Task
Java Multithreading,
level 9,
lesson 15
Locked
Restaurant (part 7)
When choosing which class to start from, try to find one that is used by others, and which does not use anything.
In our case, this is the repository of advertising videos (AdvertisementStorage).
We decided that it would be the only one in the restaurant and made it a singleton.
16
Task
Java Multithreading,
level 9,
lesson 15
Locked
Restaurant (part 8)
It's time to describe the functionality of the AdvertisementManager class.
But first we're going to need some methods in the Advertisement class.
1. Create a long amountPerImpression field in the Advertisement class.
16
Task
Java Multithreading,
level 9,
lesson 15
Locked
Restaurant (part 9)
We need an exception that will help us handle the situation where we are unable to choose commercials.
1. Create an unchecked NoVideoAvailableException in the ad package.
2. Let's take a closer look at the void processVideos() method in AdvertisementManager.
32
Task
Java Multithreading,
level 9,
lesson 15
Locked
Restaurant (part 10)
Recursion is used when the algorithm for solving the problem is the same as the algorithm for solving part of the problem.
That's just what we have. We need to do a full search of all options and choose the best of them.
16
Task
Java Multithreading,
level 9,
lesson 15
Locked
Restaurant (part 11)
We've implemented the first two of the three features. You will recall that the first was automated order preparation,
the second was commercial selection, and the third is statistics for the manager. And that's our next step.
9
Task
Java Multithreading,
level 9,
lesson 15
Locked
Restaurant (part 12)
We have several events:
*The cook prepared an order;
*The set of videos for an order has been chosen;
*There are no videos that can be shown while an order is prepared.
These are constants, so an enum is suitable for representing them.
16
Task
Java Multithreading,
level 9,
lesson 15
Locked
Restaurant (part 13)
Let's return to the StatisticsManager class's record method. It should record events in a repository.
Let's create the repository :)
The repository has a 1-to-1 relationship with the manager, i.e. there is one manager and one repository per application.
32
Task
Java Multithreading,
level 9,
lesson 15
Locked
Restaurant (part 14)
1. Create a void put(EventDataRow data) method in StatisticsStorage.
2. To allow the put(EventDataRow data) method to add the data object to the map, we need the event type (EventType).
It would make sense for the event to store its type.
32
Task
Java Multithreading,
level 9,
lesson 15
Locked
Restaurant (part 15)
Let's think about what needs to be done so that the manager can view the following:
1) advertising revenues, grouped by day;
2) cook utilization (time spent working), grouped by day;
3) list of active videos and the number of remaining impressions for each.
32
Task
Java Multithreading,
level 9,
lesson 15
Locked
Restaurant (part 16)
Let's implement the first statistics item: advertising revenues, grouped by day.
1. In the VideosSelectedEventDataRow class, create a getter for the amount field.
In the OrderReadyEventDataRow class, create a getter for the cookName field.
32
Task
Java Multithreading,
level 9,
lesson 15
Locked
Restaurant (part 17)
Let's implement the third and fourth statistics items: the lists of active and inactive videos
It will be easier to do this with access to the video repository (AdvertisementStorage class).
32
Task
Java Multithreading,
level 9,
lesson 15
Locked
Restaurant (part 18)
Currently, we have one tablet and 1 cook.
Let's create several tablets that will randomly generate orders, and we'll make two cooks.
1. In the Restaurant class, create a constant PRIVATE static int ORDER_CREATION_INTERVAL = 100.
32
Task
Java Multithreading,
level 9,
lesson 15
Locked
Restaurant (part 19)
We need to rework the main method.
First, let's make the parameters of our RandomOrderGeneratorTask constructors consistent.
Please make your method signature the same as mine:
public RandomOrderGeneratorTask(List tablets, int interval).
16
Task
Java Multithreading,
level 9,
lesson 15
Locked
Restaurant (part 20)
Fix a bug: a tablet sends its orders to all known chefs.
Expected behavior: a tablet sends its orders to a queue, and an available cook takes orders from the queue.
There are two ways to implement this functionality:
1) Each tablet stores a reference to the queue and pushes new orders to it.
32
Task
Java Multithreading,
level 9,
lesson 15
Locked
Restaurant (part 21)
We continue to fix the bug.
Now all the orders arrive in the queue, but they don't reach the cooks.
We'll make OrderManager find any available cook and give it an order. To implement this logic,
we need a deamon thread.
32
Task
Java Multithreading,
level 9,
lesson 15
Locked
Restaurant (part 22)
Unfortunately, the orders are still not being prepared in parallel. Here's how our thread from the previous task works.
It finds a cook, finds an order, gives the order to the cook using the startCookingOrder method, waits for the order to be prepared,
and only then moves on to the next order.
9
Task
Java Multithreading,
level 9,
lesson 15
Locked
Restaurant (part 23)
That's it! You can make it beautiful on your own.
For example:
1. Threads usually use the ThreadLocalRandom class instead of Random. Refactor the code: replace Random with ThreadLocalRandom.
2. Make Waiter a task so that it works like a thread (remove Observer). Make a queue of prepared orders.
GO TO FULL VERSION