Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 总是相同的线程被放置在等待中_Java_Multithreading_Wait - Fatal编程技术网

Java 总是相同的线程被放置在等待中

Java 总是相同的线程被放置在等待中,java,multithreading,wait,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

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

    }
}

有人能解释一下吗?

您设计的代码使您的显示器不公平。 如果一辆
汽车
退出插槽,它将进入循环中的下一步,因此它会立即再次尝试进入。与此同时,您的另一辆等待的
汽车被
线程唤醒。notifyAll()

嗯,那些
线程
并不是最快的。他们不能保证立即开始工作

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


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

或者,让每辆车等待一段时间(足以让它的线程屈服),然后再尝试重新喷漆。通常情况下,汽车离开停车位并不只是为了立即返回。
Thread.yield()
就足够了,
Thread.sleep()
也是一个选项。我要补充一点。既然一辆车总是停两秒钟(大约),它也应该停两秒钟。哦,伙计,生活是不公平的p我妈妈会这么说的。谢谢大家。我在退出()后添加了2秒的睡眠时间,现在效果“很好”:)我将添加队列以使其更真实,总有一天我会解决停车问题!;)您的系统上有多少CPU?将
CPU
时间分配给
线程
的决定完全取决于
JVM
线程调度程序
。而
算法因平台而异。我们无法确定
线程持有
锁的顺序。在您的系统中,可能是相同的两辆车进入
等待
状态,但在另一个系统中,处于
等待
状态的车不断变化。。