3

これは、倉庫の在庫を管理するために作成した基本的なアプリケーションです。基本的に 5 つのスレッドまたは IT 企業がそれぞれ 100 個のウィジェットを作成し、これを倉庫に保管します。これは問題なく機能しますが、倉庫の制限である 500 を超える場合があります。そのため、5 つの別々の会社がそれぞれ 100 個のウィジェットを作成し、それらを倉庫に保管して、500 個のウィジェットで停止するようにしたいと考えています。ただし、現在のところ、制限を超える場合がありますが、常にではありません。したがって、これを 3 回実行すると、2/3 で機能し、無限の量のウィジェットがウェアハウスに追加され続けるだけです。だから私の質問は、どうすればこれを修正できますか?

ここにコードがあります

public class mainClass {

    public static void main(String[] args) {

        warehouse acct1 = new warehouse(0); // create warehouse with nothing in it
        System.out.print("Reciving widgets...");
        acct1.checkBal();
        manufacturer t1 = new manufacturer(acct1, "Calcutta");  // create 5 threads (manufacturers)
        manufacturer t2 = new manufacturer(acct1, "New York");
        manufacturer t3 = new manufacturer(acct1, "Chicargo");
        manufacturer t4 = new manufacturer(acct1, "Liverpool");
        manufacturer t5 = new manufacturer(acct1, "Tokyo");

        t1.start();                 
        t2.start();
        t3.start();                 
        t4.start();
        t5.start();                 


    }
}

メーカークラス

    import java.util.*;
    public class manufacturer extends Thread {
    warehouse myAcct;               //class 'warehouse' assigned to variable MyAcct
     String name;        
        int time;
        Random r = new Random();     // imported from java.util this can be used to create a random amount of time
        int amount = 100;            // This variable is the manufacturing goal of each individual manufacture (thread)`



    public manufacturer(warehouse acct, String x) { 
        myAcct = acct;
        name = x;   // name of the thread
        time = r.nextInt(4000); // This creates the random time of anywhere between 0 and 9999

    }
    public void run() {
        while (true) {              // run forever
            try {
                sleep (time);       // Create new widgets 
            } catch (InterruptedException e) { }
                //  100 by each manufacturer
               try{
                   Thread.sleep(time);
                    System.out.printf("%s has successfully manufactured %d widgets \n", name, amount);

                     //how long do u want to sleep for?
                    //System.out.printf("%s is done\n", name);


                   myAcct.adjustBal(100); System.out.println("widgets have been stored at the central warehouse");
                   System.out.println();
                   Thread.sleep(time);
                }catch(Exception e){}

                    if (myAcct.getBal()  == 500)
                    {
                        System.out.println("The target goal of 500 widgets have been created and delivered to the central warehouse");
                        System.exit(0);
                        //myAcct.adjustBal(100);// with 100 if necessary 

                    }





            } 
            }
        }


    public class warehouse {
    int balance = 0;
    public warehouse(int openingBal) {      // constructor method
        balance = openingBal;
    }
    public synchronized void adjustBal(int amt) {
        balance += amt;         // process a transaction
        checkBal();             // then show the balance
    }
    public void checkBal() {
        System.out.print (balance);

        System.out.println();
    }
    public int getBal() {
        return balance;
    }
}
4

3 に答える 3

0

ここに競合状態があります:

        if (myAcct.getBal()  == 500)
        {
            System.out.println("The target goal of 500 widgets have been created and delivered to the central warehouse");
            System.exit(0);
            //myAcct.adjustBal(100);// with 100 if necessary 

        }

チェックと System.exit(0) の間では、システムが終了する前に、別のスレッドがウェアハウスに追加できます。

于 2012-12-19T08:53:37.720 に答える
0

共有変数への読み取りと書き込みの両方を同期してbalance、変更が確実に表示されるようにする必要があります =>getBalance()同期も行います。

ただし、問題は、他の回答で言及されている競合状態が原因である可能性が高くなります。

于 2012-12-19T08:54:30.533 に答える
0

あなたが抱えている問題は、次のシナリオが原因です:

アイテムが 400 になり、スレッド X がさらに 100 を追加していると仮定します。スレッド X がバランス チェックに到達するまでに、if statement別のスレッド Y が CPU 時間を取得してさらに 100 を追加し (合計で 600 アイテム)、バランス チェックは決して行われません。合格。

adjustBalanceメソッドは同期され、一度に 1 つのスレッドのみが制限をチェックするように追加されるため、メソッドで制限チェックを行う必要があります。

ただし、非常に重要な注意事項が 1 つあります。 System.exit(0) を使用してプロセスを途中で中止することは、プログラミングとしては非常に悪いことです。単一のデータ構造で複数のスレッドを管理する方法については、生産者/消費者について読む必要があります。

于 2012-12-19T08:55:33.800 に答える