The viewership at Woolie TV (WTV) has been in decline for years. Their program manager, Woolma, has come up with an idea for a new show that she thinks is going to be a slam dunk for the station. On recent holiday in Japan, Woolma became obsessed with watching their television shows. In particular, she found their versions of game shows to be irresistibly hilarious. Woolma plans to bring a translated version of the Japanese game show, Takeshi's Castle, to Woolieville. It will be called "Woolie Wipeout".
The idea behind the show is to make the normal citizens of Woolieville the stars of the show. They will be competing against one another to complete an obstacle course. The location for the show is in the iconic Cliffs of Winona. The two giant cliffs are separated below by the raging rapids of the Wailuku river. The construction crew has built a collection of giant rolling logs that spans across the two side of the cliff. Unfortunately, it is quite fragile and can only support a certain number of Woolies on it before it will collapse.
In the show, the Woolies race from the starting area to the obstacle course. The Woolies begin crossing the course based on their time of arrival. If they are next in line, and the maximum occupancy for the obstacle course has not been exceeded, they are allowed to cross. Because the show casts Woolies of all ages and physical conditions, they will take a different amount of time to cross the course.
While the Woolies cross the course, some will undoubtedly fall. In the event this happens, the fallen Woolies must make their way from the water, to the shore, and eventually to the back of the line of Woolies waiting to cross. As soon as a Woolie falls, the logs stop rolling. The Woolies currently crossing are "air lifted" by The Kraken's many arms and inserted into the back of the waiting line, with their crossing time reset.
The shows producer thought it would be more riveting if the Woolies that fell into the river had nothing but their wits and courage to safely make it to shore. The legal department thought otherwise and mandated that all Woolies crossing the course be equipped with life preservers to prevent lawsuits from the family members of Woolies who drown to death.
The request for life preservers threw the production company into the red. They already had spent a large portion of their budget sewing up a deal with a memorable face to host their show - the infamous octopus from the West Sea - The Kraken. Because of this, they had to cut corners on the quality of the life preservers they would use in the show. For one, the air capacity of the preservers is varied (by volume). Even worse is how badly the preservers hold air. Once blown up to full capacity, the preservers would slowly lose air over time - eventually resulting in a useless piece of plastic.
These life preserver problems threatened to ruin the concept of the show unless it was handled properly. Due to a loophole in the fine print of The Kraken's contract, the producer forced The Kraken to handle the life preserver situation. The Kraken must keep the life preservers distributed to the Woolies in "good shape". This means that no Woolie would ever be given a preserver that wouldn't last the time it takes for them to cross the course, or fall into the river and make it to shore.
And so, the Woolie Wipeout game show became a reality. It was a huge hit with the audience and brought WTV back to the number one spot in the ratings. Your job in this lab is to recreate the game show as a simulation that documents the struggle of the Woolies on the obstacle course. To achieve this, you will tap into your new found knowledge of multi-threaded programming.
This is a visual diagram of the design of the lab:
There are five classes in the design. A brief description of each class and its documentation follows.
If you did not already get the GitHub link for this assignment please see your instructor.
You should be able to run the provided code to completion. The Woolies are not implemented yet so they do nothing. The main program is run with two arguments:
If you run the program as follows:
java WoolieWipeout 0 0
The simulation should run and you should see the following output. Here, SIM refers to messages that correspond to the main class, and KRAKEN refers to messages from the host. The host also displays the state of the OBSTACLE_COURSE while running.
You will be focusing on implementing the Woolie thread class and the portion of code that the Woolies need to interact with in the ObstacleCourse class.
Keep in mind there is a separate thread class, Kraken, that you are not allowed to change. You must cooperate with it and follow the rules of the game in order to prevent a deadlock scenario from occurring. Additionally, you will be interacting with the Preserver class, which you should not change. And finally, the main class WoolieWipeout should not be modified.
This is a high level overview of how the simulation flows for the main class and run methods for Kraken and Woolie.
When a Woolie falls off the course, they indicate it to the ObstacleCourse class. The Kraken will periodically wake up and check to see if anyone has fallen. If they have, The Kraken turns off the course. This is the signal to any Woolies currently crossing that they must back up off the course, reset their crossing time, and enter the back of the queue.
This is a demonstration of the correct behavior for dealing with the falling scenario. In this example, there are 4 Woolies and 4 are allowed on the course.
KRAKEN: A Woolie has fallen! Turning off course... OBSTACLE_COURSE: ObstacleCourse(maxOnCourse=4, numOnCourse=4, fallenWoolie=true, running=false, open=true, wooliesWaiting=0) KRAKEN: A Woolie has fallen! Waiting for Woolies to exit course... KRAKEN: OBSTACLE_COURSE: ObstacleCourse(maxOnCourse=4, numOnCourse=4, fallenWoolie=true, running=false, open=true, wooliesWaiting=0) KRAKEN: A Woolie has fallen! Waiting for Woolies to exit course... KRAKEN: OBSTACLE_COURSE: ObstacleCourse(maxOnCourse=4, numOnCourse=4, fallenWoolie=true, running=false, open=true, wooliesWaiting=0) WOOLIE: Woolie_3(total=4, remaining=4, fallen=0, preserver=Optional[Preserver(id=3, buoyancy=7)]) leaves course KRAKEN: Woolie_3 returns Preserver(id=3, buoyancy=7) WOOLIE: Woolie_1(total=9, remaining=9, fallen=0, preserver=Optional[Preserver(id=1, buoyancy=15)]) leaves course KRAKEN: Woolie_1 returns Preserver(id=1, buoyancy=15) WOOLIE: Woolie_1(total=9, remaining=9, fallen=0, preserver=Optional.empty) enters line WOOLIE: Woolie_2(total=5, remaining=5, fallen=0, preserver=Optional[Preserver(id=2, buoyancy=14)]) leaves course KRAKEN: Woolie_2 returns Preserver(id=2, buoyancy=14) WOOLIE: Woolie_2(total=5, remaining=5, fallen=0, preserver=Optional.empty) enters line WOOLIE: Woolie_3(total=4, remaining=4, fallen=0, preserver=Optional.empty) enters line WOOLIE: Woolie_4(total=8, remaining=8, fallen=1, preserver=Optional[Preserver(id=4, buoyancy=7)]) leaves course KRAKEN: Woolie_4 returns Preserver(id=4, buoyancy=7) WOOLIE: Woolie_4(total=8, remaining=8, fallen=1, preserver=Optional.empty) enters line KRAKEN: All Woolies have exited course! Restarting course...
It is possible that a Woolie may cross in the time between a Woolie falls, and The Kraken wakes up and turns off the course. But once the course is turned off, no Woolie's should continue to cross until they have all cleared off the course. During this time, the Woolie waiting at the front of the line should continue to wait until the course is started up again.
The life preserver that the Woolie holds is wrapped in an Optional. Optional is a way to avoid having to use null and potentially run into the null pointer exception.
Instead of using null, if the Optional holds no preserver, it should be set to Optional.empty(). Otherwise it can be set using Optional.of(...), where ... is a non-null instance of a Preserver object.
To check if the Optional holds a Preserver, use the isPresent() method. It returns true if it holds a Preserver, and false if not.
To extract the Preserver from the Optional, use the get() method. It returns the Preserver stored within.
The Kraken will never give a Woolie a life preserver that does not have enough air in it for them to cross. When a Woolie returns a preserver, if it has no air left in it, it is destroyed. Otherwise it is pushed onto the front of a stack of preservers. While in the stack, the preservers continue to maintain the same amount of air they had in them when they were first added. When a Woolie requests a preserver, the Kraken first checks the top of the stack. If that preserver has enough air in it, he returns it to them. Otherwise he creates a new preserver that has at least enough air for that Woolie to cross.
Several sample runs with a different number of Wolies and a maximum number on course are provided. Keep in mind that due to the execution of the threads, and the random state, that no two runs are ever guaranteed to display even remotely the same order of output.
This is the suggested approach for how you should implement this lab.
You should review the lectures notes from this week that are posted here. Also make note of the zip file that contains all the source code from lecture. In particular, the second producer consumer example shows the basics of the thread cooperation you will need to use in this lab.
Zip your your entire src folder and name the zip file lab6.zip. Upload your zip file to the MyCourses dropbox by the deadline.