Assignment 3: Synchronization
Due: Monday, November 12, 11:59:59 p.m.
Set up
Go to GitHub Classroom to get to the assignment and create your own repository.
Clone your repository. For this assignment, you don't need to run on your VM.
Problems
- Tweedledum and Tweedledee are separate threads executing their respective procedures. The code below is intended to cause them to forever take turns exchanging insults through the shared variable X in strict alternation. The
Sleep()
andWakeup()
routines operate as follows:Sleep
blocks the calling threadWakeup
unblocks a specific thread if that thread is blocked, otherwise its behavior is unpredictable.
void Tweedledum() { while(1) { Sleep(); x = Quarrel(x); Wakeup(tweedledee_thread); } } void Tweedledee() { while(1) { x = Quarrel(x); Wakeup(tweedledum_thread); Sleep(); } }
In the
Tweedles.txt
text file, answer the following questions:- The code shown above exhibits a well-known synchronization flaw. Briefly outline a scenario in which this code would fail, and the outcome of that scenario.
- Show how to fix the problem by replacing the
Sleep
andWakeup
calls with semaphoreP
(down) andV
(up) operations. - Implement
Tweedledum
andTweedledee
correctly using a mutex and condition variable (not a monitor).
- The Rollercoaster Problem: There are two types of threads:
TrainThread
models the roller coaster train. TheTrainThread
should wait while passengers load. When the train is full (and only when it is full), it should run a loop around the track. After completing a loop around the track, it should wait for all of the passengers to unload. Once the passengers unload, the train should again load passengers.PassengerThread
models a passenger. ThePassengerThread
s should wander around the amusement park for a random amount of time before getting in line for the roller coaster. Once in line, a passenger should load onto the train, wait until the train runs its loop around the track, and unloads. Note: the "line" in this case need not necessarily be first-come-first-served. However, those passengers that get on a given train must be the same ones that get off of that train.
Some starter code for this problem is provided in
RollerCoaster.java
. This starter code provides unsynchronized versions of theTrainThread
and thePassengerThread
that display nicely formatted output.Run this code and understand the output before you start modifying the code. The output will be similar to (though not necessarily the same as) the example output below:
$ java RollerCoaster 4 2 Passenger: | Train: Wandering In Line On Train Off Train | Loading Running UnLoading ----------------------------------------------------------------+----------------------------------------- | Train | Train Passenger 0 | Passenger 1 | Passenger 2 | Passenger 3 | Passenger 2 | Passenger 2 | Passenger 2 | | Train | Train | Train | Train | Train | Train Passenger 0 | Passenger 0 | Passenger 0 | Passenger 1 | Passenger 1 | Passenger 1 | Passenger 3 | Passenger 3 | Passenger 3 |
The output for 4 passengers, with two passengers per train, shows that initially the train is loading and then it (incorrectly) runs with no passengers on it. Passenger 2 then gets in line, gets on train, and gets off the train while the train is unloading. Later, three passengers get on the train while the train is moving.
Your job is to synchronize the code to ensure that both the
TrainThread
and thePassengerThread
s behave as specified. Your threads should not busy-wait--that would not be efficient. A correct solution might generate output similar to the following:$ java RollerCoaster 4 2 Passenger: | Train: Wandering In Line On Train Off Train | Loading Running UnLoading ----------------------------------------------------------------+----------------------------------------- | Train Passenger 0 | Passenger 2 | Passenger 1 | Passenger 3 | Passenger 0 | Passenger 0 | Passenger 2 | Passenger 2 | | Train | Train Passenger 0 | Passenger 2 | | Train Passenger 3 | Passenger 3 | Passenger 1 | Passenger 1 | | Train | Train Passenger 3 | Passenger 1 | | Train
There are two restrictions on what you may do in your solution to this problem:
- You should declare all of your shared variables as
public static
in RollerCoaster. You will then be able to access them in both the thread classes. - You may only add code to
run
in the thread classes to accomplish the required synchronization.
In a
README
file, discuss your solution and justify that it is correct.
Recommendations
Understand the problem and the existing code before any modifications. Think about the key questions for synchronization problems and how to answer them for this problem. Review the example solutions and code. Your solution should not be overly complicated to explain.
Submission
GitHub Classroom will make a snapshot of your repository at the deadline. It contains only the code that you pushed to the repository.
Ask well before the deadline if you need help turning in your assignment!
Grading (100 pts)
You will be graded on- (30) Answering the questions with the Tweedles
- (65) Correctly solving the Roller Coaster problem
- (5) Justifying the correctness of your Roller Coaster solution in a README file