【问题标题】:Always the same thread is put on waiting总是相同的线程处于等待状态
【发布时间】:2013-02-02 19:36:36
【问题描述】:

我对这个简单的练习有疑问: 有一个停车场,一次最多可停 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();

    }
}

谁能解释一下?

【问题讨论】:

  • 您的系统上有多少个 CPU?
  • CPU 时间分配给thread 的决定完全取决于JVM Thread Scheduleralgorithm 因平台而异。我们无法确定 threads 将持有 lock 的顺序。在您的系统中,可能有两辆汽车进入WAITING 状态,但在其他系统中,处于WAITING 状态的汽车不断变化..

标签: java multithreading wait


【解决方案1】:

您设计的代码使您的监视器不公平。 如果Car 退出插槽,它将进入循环的下一步,因此它会立即尝试再次进入。与此同时,您的其他等待 Cars 被 Thread.notifyAll() 唤醒。
好吧,那些Threads 并不是最快的。他们不能保证立即开始工作......

刚刚退出插槽的 Car 会发生什么情况?它试图再次停车。而且由于它的线程没有等待它不需要重新开始工作......它会立即停放。
您可能想要的是一个队列。将您的请求Car 添加到Queue,如果发生输入,请先通知您等待时间最长的Car。正如 Jan 建议的那样,另一种方法是让那些退出 Cars 的人稍等一下,让其他停车者有机会。这可以通过在退出的Car 上使用Thread.yield()Thread.sleep() 来实现(退出完成后)。

你制作的这个场景对所有相关方来说都很烦人。诚实的等待Cars 一直在等待他们的位置,而自我停车者永远不会回家;)

【讨论】:

  • 或者让每辆车在尝试重新停车之前等待一段时间(足以让其线程屈服)。通常,汽车不会为了立即返回而离开停车位。
  • Thread.yield() 就足够了,Thread.sleep() 也是一个选项。我会补充的。
  • 由于汽车总是停放两秒钟(大约),它也应该停放两秒钟。
  • 哦,伙计,生活不公平! :p 这就是我妈妈会说的。
  • 谢谢大家。我在 exit() 之后添加了 2 秒睡眠,现在它工作“正常”:) 我将添加队列以使其更真实,总有一天我会解决停车问题! ;)
猜你喜欢
  • 2018-01-17
  • 2014-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多