Assignment #2: Threads and Critical Sections
This is a tricky assignment that illustrates threads, synchronization, and
critical sections.
You will write a simulation of the Ticketmaster Phone system.
Here we will assume that there are five lines, but only three operators.
When a phone call arrives, we see if there is a free line.
If so, the phone rings; otherwise it is busy.
Once the phone rings, we wait until there is a free operator,
and when we get one, we pretend to get service.
Each phone call is represented by a thread, and you will have
more threads running than phone lines.
There are several components to the project.
Semaphor and Mutex
First you will complete the Semaphor and write the
Mutex class.
Semaphor.java is your starting point.
A Semaphor is use to control entry to a critical
section with a limit of how many threads are allowed to
be simultaneously active.
To enter the critical section you must gain ownership with
obtain, and upon leaving the
critical section you should release so
a waiting thread can enter.
The Semaphor maintains the limit of threads concurrently allowed
in its critical section, and a list of the threads currently
(in an ArrayList).
The skeleton is already written, you need to follow the
embedded comments to complete the code.
A Mutex is a semaphor with a limit of one thread
in the critical section.
Use inheritance for a quick implementation.
The PhoneCall Class and main
A phone call is represented by a PhoneCall class
that contains a caller's id as private data member, set in its
constructor.
PhoneCall will extend Thread and provide
a run method.
It will also contain a host of static data members,
including semaphors and mutexes that are shared and control
the synchronization.
To start with, implement a constructor, and
provide a run that simply prints a message, so you
know that the thread is running, sleeps for a few seconds
(use Thread.sleep), and then prints a message
before the thread ends.
Later you will do the meaty part of the simulation.
Your main routine will declare an array of threads that
will represent each phone call.
Then, write a loop that constructs PhoneCall
objects to initialize the array.
Then, write a loop that starts each PhoneCall thread.
When main terminates print a message that the simulation
is over.
If you run the program, you'll notice that the message comes
early.
You will want main to block until all the other
threads complete and to do that, you should have another
loop that uses join on each thread.
The Synchronization
Once you have the threads going, you'll want to do the
real part of the simulation.
Your PhoneCall class should declare the following static data:
private static int NUM_OPERATORS = 3;
private static int NUM_LINES = 5;
private static int connected = 0; // Callers that are connected
private static Mutex connectedMutex = new Mutex( );
private static Semaphor operators = new Semaphor( NUM_OPERATORS );
The variable connected tells how many callers are currently
connected (a call attempt is declared busy if connected==NUM_LINES).
Access to connected must be controlled by a critical section, and
is done by using the connectedMutex.
The operators semaphor is used once a call connects.
Here is a sketch of the run method for PhoneCall:
- Print that an attempt to connect has been made
- Check if the connection can be made
- You'll need to test connected in a critical section
- If the line is busy, exit the critical section, print a message, and terminate run
- If the line is not busy, update connected, exit the
critical section, and print a message, and continue to the next step
- Wait for an operator to be available (use a semaphor)
- Print a message that the order is being taken
- Simulate an order by sleeping for a few seconds
- Print a message that the order is complete (and update the semaphor)
- Update connected (do you need a critical section?)
- Print a message that the call is over
What to Submit
In the usual format, submit all of your source code and
the result of running with 10 phone calls.
In main, delay the last two phone calls enough so that the
line will not be busy.