线程:忙等待 - 空循环 [英] Threads: Busy Waiting - Empty While-Loop
问题描述
在我们上大学的课程中,我们学习了主题
并使用忙碌等待方法作为 Car $的示例c $ c>等待
TrafficLight
。对于此任务,我们构建了三个类:
During our lessons in the university, we learned about Threads
and used the "Busy Waiting" method for an example of a Car
waiting at a TrafficLight
. For this task we build three classes:
-
TrafficLight(实现Runnable)
-
Car(实现Runnable)
-
Main
TrafficLight (implements Runnable)
Car (implements Runnable)
Main
在我们的 Main
类中,我们开始两个线程
s, Car
之一,以及 TrafficLight
之一。 Car
具有布尔属性 hasToWait
。这个类中的 run()
方法的工作方式是,它通过而
循环工作,只要 hasToWait == true
。要更改此设置,我们在 Car
类中有 notifyCar()
方法,该方法由<$ c使用$ C>交通灯。 TrafficLight
中的 run()
方法通过 Thread.sleep()$运行c $ c>模拟一定的等待时间。
In our Main
class we start two Thread
s, one of Car
, and one of TrafficLight
. The Car
has the boolean attribute hasToWait
. The run()
method in this class works the way, that it works through a while
loop as long as hasToWait == true
. To change this, we have the notifyCar()
method in the Car
class, which is used by the TrafficLight
. The run()
method in TrafficLight
runs through a Thread.sleep()
to simulate a certain time of waiting.
我的教授一切正常,但最终我遇到了严重问题。只要 Car
类中的 while
循环为空。当我输入 System.out.println()
- 不为空时,它可以正常工作。但是如果Syso为空,则结果是不显示 Run
方法的文本。
当 TrafficLight
中的 Thread.sleep()
为 0时,它也正常工作
。比使用空而
循环。
Everything works fine at my Prof's but eventually I have serious problems with it. As long as the while
loop in the Car
class is empty. When I put in a System.out.println()
- which is not empty, it works. But if the Syso is empty, the result is no displaying of the Text of the Run
method.
Also it's working when the Thread.sleep()
in TrafficLight
is 0
. Than it works with an empty while
loop.
这是我的代码:
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");
}
}
TrafficLight.java:
TrafficLight.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();
}
}
Main.java:
Main.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();
}
}
问题出在哪里?为什么它适用于我的教授而不是我的电脑?我在Eclipse Juno中获得了代码1:1,使用 JRE 1.7
Where is the problem? Why does it work at my profs but not at my computer? I got the code 1:1 in my Eclipse Juno, using JRE 1.7
推荐答案
除了其他答案中所说的一切之外(只需替换你的 hasToWait
在该答案中已完成
,代码在添加 println时开始工作的原因
如下:
In addition to everything said in this other answer (just substitute your hasToWait
for finished
in that answer), the reason why the code starts working when you add a println
is as follows:
-
println
是 synchronized 方法; - 你在两个线程中调用它;
- 这会在之前发生 >两个线程之间的关系;
- 因此对子线程的布尔标志的写入变得可见。
println
is a synchronized method;- you call it in both threads;
- this creates a happens-before relationship between the two threads;
- therefore the write to the boolean flag becomes visible to the child thread.
你可以说它主要是开始工作:你正在捎带 println
中正在进行的同步。
You could say that it starts working mostly by accident: you are piggybacking on the synchronization going on in println
.
这篇关于线程:忙等待 - 空循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!