[英]java concurrency, producer(broker) and consumer
我需要使用並發的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[]
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.