International Buillion and Metals corporation (IBM) is the worlds largest trading company in precious metals. They have contracted with you for a new trading system written in Java. For this assignment, you will write a pilot system that handles just three metals: Gold, Platinum, and Uranium. IBM brokers get metals from refiners and supply them to consumers. The refiners will be represented in your program by a single Java thread that periodically delivers shipments of refined metals to the brokers. The brokers are represented by three monitors, one for each metal. There may be any number of Consumer threads.
Each broker maintains a stock of all three metals, but is a "supplier" for only one of them, called its "specialty." From time to time, the refiner delivers a shipment of refined metal to the broker who is the supplier for it. For example, the refiner might deliver 30 ounces of gold to the gold supplier. Consumers periodically place purchase orders with brokers. Each order specifies the number of ounces of each metal. It can be placed with any broker. A broker will fill the order from its own stock if possible. If the supplier for metal M cannot fill an order because it does not have enough of M on hand, it just waits until it gets more from the refiner, but if it is short some other metal, it attempts to get it by trading with the supplier for that metal. To keep things simple, we will assume, somewhat unrealistically, that ounces of gold, platinum, or uranium are all equally valuable. That is, three ounces of gold can be swapped for three ounces of uranium or three ounces of platinum.
For example, suppose a consumer places an order with the gold broker for 4 ounces of gold and 1 ounce of platinum.
A broker treats a request from another broker just like an order from a consumer. If it can fill it immediately, it will. Otherwise, since the request must be for its specialty metal, it will just wait until it gets more from the refiner.
We have supplied three classes, Project2, Refiner, and Consumer, and two interfaces, IBM and Broker. The classes Refiner and Consumer are meant to be used as threads (that is, they implement Runnable). You are expected to write a class BrokerImplementation that implements Broker. BrokerImplementation is a "monitor" class, meaning that a broker does not act on its own, only in response to a call from a refiner or consumer. Project2 is the main class. It creates one refiner thread and some number (specified on the command line) of consumer threads and starts them running.
From time to time the refiner thread delivers a load of some metal to the supplier of that metal by calling the Broker method
public void deliver(int ounces);From time to time a consumer places an order by contacting a random broker and calling the Broker method
public void get(int[] order);The array order contains one non-negative integer for each metal, indicating how much of that metal is desired. For example, to get three ounces of gold and one ounce of uranium, a consumer might use code like this:2
int[] order = new int[METALS]; order[GOLD] = 3; order[URANIUM] = 1; int whichBroker = Project2.randInt(METALS); Project2.specialist(whichBroker).get(order);As you can see, the class Project2 provides several handy utilities as static methods. We will explain these in more detail below.
A broker who does not have enough of a metal on hand to satisfy a request may try to get more from the supplier of that metal by calling the method
public void swap(int what, int ounces);This method indicates that the calling broker is willing to swap ounces ounces of metal what for ounces ounces of the supplier's specialty. For example, the call
Project2 . speciality(GOLD) . swap(PLATINUM, 2);indicates that the caller is willing to swap 2 ounces of platinum for two ounces of gold. After the call returns (calls to get and swap never fail, but they may delay the caller for a while), the caller should subtract 2 from its supply of platinum and add 2 to its supply of gold.
When a broker cannot satisfy a get or swap request because it does not have enough of the metal in which it specializes, it blocks the caller (using the Java wait method) until it can. A broker that is blocked waiting for something should continue to accept calls from other consumers or brokers.
Your solution must be deadlock-free, but it does not have to be "fair". In particular, you do not have to prevent starvation (an unlucky consumer who repeatedly gets passed over).
mkdir project2 cd project2 cp ~cs537-2/public/html/source/p2/*.java .Read the documenatation online.
WARNING: These classes may need to be updated from time to time. Check the Frequently Asked Questions (FAQ) frequently to see if you need to fetch a fresh copy.
In addition to the main method, Project2 provides several public static methods.
try { wait(); } catch (InterruptedException e) { Project2.debug(... whatever ...); throw new StopThread(); }The throw is important; without it, your program will just hang, since the main method does a join on each of the consumer threads before exiting.
The getProduction() method is used by Project2.main to audit the global state when the system shuts down.
Any variable that may be accessed by more than one process should only be accessed inside a critical section.In the context of this project, that means that fields of class BrokerImplementation should only be accessed inside synchronized methods. On the other hand, there's another rule that will help you avoid deadlocks:
A synchronized method should never call a synchronized method of another object.In the context of this project, that means that BrokerImplementation.get cannot be synchronized because it needs to call BrokerImplementation.swap in another broker. Instead, define your own private synchronized methods to read and/or update fields of BrokerImplementation and call them from BrokerImplementation.get.
There will undoubtedly be more hints provided by your fellow students. Watch the Frequently Asked Questions (FAQ) for more information.
1 However, at first you should probably look only at the first 3 questions in the FAQ. The remaining questions involve "advanced" topics that will only confuse you if you're trying to get the basic functionality working.
2The constants METALS,
GOLD, PLATINUM, and URANIUM are defined in interface
IBM, but because Consumer implements IBM, it is ok to
omit
"