UNIVERSITY OF WISCONSIN-MADISON
Computer Sciences Department
We have written for you a class called Bridges. This class has the following methods that you can call. (More detailed documentation is also available).
Each person is a thread running a Person class, which you must write, that implements the following interface (see also the complete specification.)
Use a ``monitor'' (a Java class with synchronized methods) as the synchronization mechanism for your solution. Create an instance of the monitor in the main() method and save it as a static field of the ``main'' class so that it can be easily referenced from Person.run().
Your solution must obey the following rules:
If you violate the above rules or call the Bridges methods incorrectly, the people will fall in the river and drown (actually, an exception will be thrown, either Drowning or IllegalArgumentException ).
You must prepare two solutions to this problem. In the first solution, there is no fairness guarantees. There is a separate waiting line for each bridge. A newly arriving person gets in the shortest waiting line and waits for a chance to cross that bridge. However, there is no alternation guarantees for people wanting to go in both directions. If some people are going east on one bridge, newcomers going east can get onto the bridge as long as the capacity is not exceeded, even if there are already people waiting to go west on the bridge. Thus, in this solution, people waiting at either the east or the west end of the bridge may be starved to death (since there is no fast-food place at either end of the bridges).
In the second solution, people on both sides cross the bridge based on the First-Come-First-Cross discipline. You can assume that people never arrive at the opposite ends of the bridge at exactly the same time.
Which solution gives better performance in terms of average waiting time?
Create a new directory for this project. You will need to define at least three classes for this project, the ``main'' class, the class Person, and a monitor class. Put the source for each class in a separate .java file (with the same name as the class). Copy the implementation of the Bridges and Drowning classes to your working directory.
cp /p/course/cs537-cao/public/project2/*.class .Then compile and run your program as usual.
javac Project2.java time java Project2The word ``time'' at the beginning of the second command causes Unix to print a message after the command completes indicating how much CPU time you used. This will give a hint how efficient your solution is (see below).
More details on tests you should run will be posted before the due date.
For the second solution, you will need a monitor class to coordinate access to the bridges. We'll call it CrossingGuard for this discussion. This class will have to keep track of the state of all the bridges (how many people are currently crossing each bridge and which way they are going). There is no way of getting this information directly from Bridges. (There is a toString method, but that's just for debugging.) CrossingGuard will have a method a person calls when he wants to cross the river.
You should not call Bridges.cross() from a synchronized method of CrossingGuard. If you do so, everything may seem to work fine, but you will get terrible performance. When a thread gets blocked in Bridges.cross(), it will still be holding the monitor lock for CrossingGuard, preventing any other thread from entering any method of CrossingGuard. The result will be that only one person will cross the river at a time, regardless of how many bridges there are and regardless how many people each bridge can hold. Instead, you should have two synchronized methods, one that blocks the caller until it is safe to call Bridges.cross() and the other to be called after Bridges.cross() returns.