gpt4 book ai didi

java并发,生产者(经纪人)和消费者

转载 作者:行者123 更新时间:2023-12-01 14:50:47 27 4
gpt4 key购买 nike

我需要有关使用并发的 Java 作业的帮助。我遇到的问题是在 get 方法上,我找不到任何问题。然而,感觉它没有被正确访问,或者它没有做它应该做的事情。总而言之,问题是我得到了所有金属,但我没有给消费者任何金属,我不知道这是怎么发生的。如果我需要提供任何其他信息,请告诉我。

每个经纪人都持有所有三种金属的库存,但只是其中一种金属的“供应商”,称为“专业金属”。精炼厂有时会将一批精炼金属交付给其供应商经纪人。例如,精炼商可能向黄金供应商交付 30 盎司黄金。消费者定期向经纪人下订单。每个订单都指定每种金属的盎司数。它可以放置在任何经纪人处。如果可能的话,经纪商将从自己的股票中填写订单。如果金属 M 的供应商因为手头没有足够的 M 而无法履行订单,那么它只会等待,直到从精炼厂获得更多。但如果它做空某种其他金属,它会尝试通过与供应商交易该金属来获得它。为了简单起见,我们假设(有些不切实际)盎司的黄金、铂或铀都具有同等值(value)。也就是说,三盎司黄金可以兑换三盎司铀或三盎司铂。

抱歉,我无法显示使用 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 上同步大块可能会对性能产生影响。

编辑:我还建议(尽管您没有要求这样做)您的同步块(synchronized block)中没有 wait() 。这将导致死锁,因为同步块(synchronized block)内的线程将在等待时阻塞 metals[]

关于java并发,生产者(经纪人)和消费者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14879783/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com