主题:忙等待 - 空的 While 循环

Kai*_*ear 5 java eclipse multithreading busy-waiting

在大学的课程中,我们学习Threads并使用了“忙等待”方法作为CarTrafficLight. 对于这个任务,我们构建了三个类:

  • TrafficLight (implements Runnable)
  • Car (implements Runnable)
  • Main

在我们的Main班级中,我们开始了两个Threads,一个是Car,一个是TrafficLight。在Car具有布尔属性hasToWaitrun()此类中的方法的工作方式是,while只要hasToWait == true. 为了改变这一点,我们notifyCar()Car类中有一个方法,它被TrafficLight. 中的run()方法TrafficLight通过aThread.sleep()来模拟一定的等待时间。

在我的教授那里一切正常,但最终我遇到了严重的问题。只要类中的while循环Car为空。当我把一个System.out.println()-这是不是空的,它的工作原理。但如果Syso 为空,则结果是不显示方法的Text Run。当Thread.sleep()inTrafficLight0. 比它适用于空while循环。

这是我的代码:

汽车.java:

package trafficlight;

public class Car implements Runnable {

    private boolean hasToWait = true;

    public void run() {
        this.crossTrafficLight();
    }

    public void crossTrafficLight() {
        while(hasToWait){ for(int i = 0; i<20; i++){System.out.println("123");}} // Busy waiting
        System.out.println("Auto fährt über Ampel");
    }

    public void notifyCar() {
        this.hasToWait = false;
        System.out.println("Test");
    }
}
Run Code Online (Sandbox Code Playgroud)

交通灯.java:

package trafficlight;

public class TrafficLight implements Runnable {
    private Car car;

    public TrafficLight(Car car) {
        this.car = car;
    }

    @Override
    public void run() {
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        this.car.notifyCar();
    }
}
Run Code Online (Sandbox Code Playgroud)

主.java:

package trafficlight;

public class Main {

    public static void main(String[] args){
        Car car = new Car();
        TrafficLight tl = new TrafficLight(car);

        new Thread(car).start();
        new Thread(tl).start();
    }

}
Run Code Online (Sandbox Code Playgroud)

问题出在哪儿?为什么它适用于我的教授,但不适用于我的计算机?我在 Eclipse Juno 中得到了 1:1 的代码,使用JRE 1.7

Mar*_*nik 5

除了这个其他答案中所说的所有内容(只需在该答案中替换您的hasToWaitfor finished),当您添加 a 时代码开始工作的原因println如下:

  • println是一种同步方法;
  • 你在两个线程中调用它;
  • 这在两个线程之间创建了一个发生之前的关系;
  • 因此对布尔标志的写入对子线程可见。

您可以说它开始工作主要是偶然的:您正在捎带正在进行的同步println