2

この簡単な演習に問題があります。一度に最大 4 台の車を駐車できる駐車場があり、6 台の車があります。

問題は、4台の車が入った後、次の2台の車が待機状態になり、まったく入らないことです。

画面に表示されるのは次のとおりです。

Car 1 in
Car 2 in
Car 5 in
Car 6 in
Car 4 is waiting
Car 3 is waiting
Car 1 out
Car 1 in
Car 3 is waiting
Car 4 is waiting
Car 5 out
Car 5 in
Car 2 out
Car 2 in
and so on..

ここにクラスがあります:

public class Car extends Thread{

    int idCar;
    Monitor monitor;

    public Car(int id, Monitor monitor){
        idCar=id;
        this.monitor=monitor;
    }

    public void run(){
        while(true){
            monitor.enter(idCar);
            try{
               sleep(2000);
            }catch(Exception e){}
            monitor.exit(idCar);
        }
    }

}

public class Monitor {

    int maxSpots;
    int parkedCars;

    public Monitor(int maxSpots){
        this.maxSpots=maxSpots;
        parkedCars=0;
    }

    public synchronized void enter(int idCar){
        while(parkedCars==maxSpots){
            try{
                System.out.println("Car "+idCar+" is waiting");
                wait();
            }catch(Exception e){}
        }
        ++parkedCars;
        System.out.println("Car "+idCar+" in");
        notifyAll();

    }

    public synchronized void exit(int idCar){
        /*while(parkedCars==0){   // i'm not sure if this check is needed, because
            try{              // no car will ever get out, if it's not in.
                wait();
            }catch(Exception e){}
        }*/
        --parkedCars;
        System.out.println("Car "+idCar+" out");
        notifyAll();

    }

}

public class Parking {

    public static void main(String[] args){

        Monitor m = new Monitor(4);

        Car c1 = new Car(1, m);
        Car c2 = new Car(2, m);
        Car c3 = new Car(3, m);
        Car c4 = new Car(4, m);
        Car c5 = new Car(5, m);
        Car c6 = new Car(6, m);

        c1.start();
        c2.start();
        c3.start();
        c4.start();
        c5.start();
        c6.start();

    }
}

誰か説明してくれませんか?

4

1 に答える 1

6

モニターが不公平になるようにコードを設計しました。aCarがスロットを出ると、ループの次のステップに入り、すぐに再び入ろうとします。その間、他の待機中Carの s は によって起こされThread.notifyAll()ます。
まあ、それらThreadは最速ではありません。遅滞なく作業を開始できるとは限りません...

Carスロットを出たばかりの はどうなりますか? 再び駐車しようとします。そして、そのスレッドは待機していないので、再び作業に戻る必要はありません...すぐに停止します。
あなたが望むかもしれないのはqueueです。Car要求を aに追加し、入力が発生した場合は、最長の待機を最初Queueに通知します。Carジャンが提案したように、別のアプローチは、他のパーカーにチャンスを与えるために、退場する人をCar少し待たせることです. これは、使用Thread.yield()またはThread.sleep()終了時Car(終了後) に実行できます。

あなたが作成したこのシナリオは、すべての関係者にとって非常に迷惑です。正直な待っCarている人は自分のスロットを永遠に待っており、エゴパーカーは家に帰ることはありません;)

于 2013-02-02T19:48:33.530 に答える