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.
To enter the critical section you must gain ownership with acquire, and upon leaving the critical section you should release so a waiting thread can enter. Note: there is a Semaphore class in the Java 1.5 library, but please write your own, for the practice. Do it using Lock and Condition objects. (You can also do it via monitors, and synchronized, but that is old style.) The Semaphor is implemented as follows. First, it maintains the limit of threads concurrently allowed in its critical section, and a Map of the threads (in a HashMap) currently in the cricital section. In the Map, the key represents a thread already in the critical section, and the value represents the number of times the thread has called acquire but not release. In other words, the Semaphor is reentrant. The skeleton is already written, you need to follow the embedded comments to complete the code, and you also need to put in the calls to lock and unlock in appropriate places.
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.
private static int NUM_OPERATORS = 3; private static int NUM_LINES = 5; private static int connected = 0; // Callers that are connected private static Lock connectedLock = new ReentrantLock( ); 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). The main issue is that the test of connected and the subsequent update of connected need to be considered an atomic, single operation (much like in the bank account withdraw method). Access to connected can be controlled by a critical section, and is done by using the connectedLock. The operators semaphor is used once a call connects. Here is a sketch of the run method for PhoneCall:
Test your program by running with 10 phone calls. In main, delay the last two phone calls enough so that the line will not be busy.