我需要使用并发的Java分配的帮助。我遇到的问题是get
方法,找不到任何问题。但是,感觉好像未正确访问它,或者未按预期执行操作。综上所述,问题在于我得到了所有的金属,但我没有给消费者任何东西,我不知道那是怎么回事。让我知道是否需要提供其他信息。
每个经纪人都保留所有三种金属的库存,但仅是其中一种的“供应商”,称为“专业”。精炼厂会不时向其经纪人经纪人运送精炼金属。例如,精炼厂可能向黄金供应商交付30盎司的黄金。消费者定期向经纪人下订单。每个订单指定每种金属的盎司数。它可以与任何经纪人一起放置。如果可能的话,经纪人将用自己的库存来填写订单。如果金属M的供应商由于手头上没有足够的M而无法填写订单,它会等到从精炼商处获得更多。但是,如果某种其他金属做空,它会尝试通过与供应商进行交易来获得该金属。为简单起见,我们将有点不切实际地假设盎司黄金,铂金或铀都具有同等价值。也就是说,可以将三盎司的黄金换成三盎司的铀或三盎司的铂。
抱歉,我无法显示使用BrokerImplementation的类。我不能,因为它们都是.class文件,并且认为上传位代码没有任何帮助。
在此先感谢您提供的任何帮助。
// This class overrides all it's methods from the Broker interface
public class BrokerImplementation implements Broker, IBM {
int specialty;
int[] metals = {0, 0, 0};
/**
* The constructor takes a single integer parameter, the code for the metal
* which this broker supplies.
*
* @param specialty
*/
public BrokerImplementation(int specialty) {
this.specialty = specialty;
}
/**
* This method is used by Project2.main to audit the global state when the
* system shuts down. The Broker should fill in result with the amount of
* each metal it has on hand.
*
* @param result
*/
@Override
public void getAmountOnHand(int[] result) {
//GOLD, PLATINUM, URANIUM are are constants in the IBM interface
//which correspond to the indexes {0, 1, 2}
result[GOLD] = metals[GOLD];
result[PLATINUM] = metals[PLATINUM];
result[URANIUM] = metals[URANIUM];
}
/**
* A consumer calls this method to place an order. The argument is a
* three-element array indicating the number of ounces of gold, platinum,
* and uranium desired. It should return only when the order has been
* filled.
*
* @param metals
*/
@Override
public void get(int[] order) {
for(int i = 0; i < 3; i++){
if (metals[i] > order[i]) {
metals[i] -= order[i];
} else {
this.swap(i, order[i] - metals[i]);
this.get(order);
try {
wait();
} catch (InterruptedException ex) {
Logger.getLogger(BrokerImplementation.class.getName()).log(Level.SEVERE, null, ex);
}
notifyAll();
}
}
}
/**
* Another broker calls this method to swap one metal for another. The what
* argument indicates one of the metals; the other one is the metal in which
* this broker specializes. The ounces argument indicates how many ounces to
* swap.
*
* @param what
* @param ounces
*/
@Override
public void swap(int what, int ounces) {
synchronized (this) {
if (metals[specialty] >= ounces) {
metals[specialty] -= ounces;
metals[what] += ounces;
} else {
notifyAll();
try {
wait();
} catch (InterruptedException ex) {
Logger.getLogger(BrokerImplementation.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
/**
* The refiner calls this method to deliver a load of metal to the broker.
* The argument ounces is a number of ounces. The metal is the one this
* broker supplies.
*
* @param ounces
*/
@Override
public void deliver(final int ounces) {
System.out.println("available " + metals[specialty]);
metals[specialty] += ounces;
}
最佳答案
专门查看get(int[] order)
方法,有几件事您尚未考虑。由于您在问题中提到了多线程,因此我假设多个线程可能一次都调用此方法。鉴于此事实,您尚未考虑对共享资源metals[]
的同步访问。 -=
操作不是线程安全的,在该数组上的迭代也不是安全的。另外,当您添加同步时,如果您担心性能,请尝试最小化您要同步的内容,因为在this
上同步大块会影响性能。
编辑:我还建议(尽管您没有要求这样做)您在同步块中没有wait()。这将导致死锁,因为同步块中的线程将在等待时阻塞metals[]
。