簡體   English   中英

Java並發,生產者(經紀人)和消費者

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM