Reputation: 43
i have a problem with this simple exercise: There is a parking area, that allows max 4 cars at a time and there are 6 cars.
The problem is that after 4 cars have entered, the next 2 cars go in waiting state and never enter.
Here is what i get on the screen:
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..
Here the classes:
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();
}
}
Could anyone explain please?
Upvotes: 2
Views: 158
Reputation: 3510
You designed your code so that your monitor is not fair.
If a Car
exits the slot it enters the next step in the loop, thus it tries to enter again instantly. In the meantime your other waiting Car
s get woken up by Thread.notifyAll()
.
Well, those Thread
s aren't the fastest. They are not guaranteed to start working without a delay...
What happens to your Car
, that just exited the slot? It tries to park in again. And as its thread hasn't waited it doesn't need to get back to work again... it parks in instantly.
What you might want is a queue. Add your requesting Car
to a Queue
and if an enter happens, notify your longest waiting Car
first. Another approach, as Jan suggested, would be to let those exiting Car
s wait a bit to give other parkers a chance. This could be achieved via using Thread.yield()
or Thread.sleep()
on the exiting Car
(after it`s done with exiting).
This scenario you produced is quite annoying for all parties concerned. The honest waiting Car
s are waiting for ever for their slot and the ego-parkers never get back home ;)
Upvotes: 6