总是在同一个线程上等待

Gib*_*731 2 java multithreading wait

我对这个简单的练习有一个问题:有一个停车区,一次最多允许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..
Run Code Online (Sandbox Code Playgroud)

这里的课程:

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();

    }
}
Run Code Online (Sandbox Code Playgroud)

有人可以解释一下吗?

Zhe*_*dar 6

您设计了代码,以使您的显示器不公平.如果Car退出插槽,它将进入循环中的下一步,因此它会立即尝试再次进入.在此期间,你的其他等待Car被唤醒了Thread.notifyAll().
嗯,那些Thread不是最快的.他们不能保证不会延误地开始工作......

发生在你什么Car,只是退出插槽?它试图再次停放.由于它的线程没有等待它不需要再次恢复工作......它立即停放.
你可能想要的是一个队列.将您的请求添加Car到a Queue,如果输入发生,请先通知您最长的等待Car.正如Jan所建议的那样,另一种方法是让那些离开Car的人稍等一下给其他游客一个机会.这可以通过使用Thread.yield()Thread.sleep()退出Car(在完成退出之后)来实现.

你制作的这个场景对所有相关方来说都很烦人.诚实的等待Car着他们正在等待他们的位置,而自我沉没的人永远不会回家;)