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 (implements Runnable)
Car (implements Runnable)
Main
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.
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.
Here is my code:
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");
}
}
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();
}
}
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();
}
}
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
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
is a synchronized method;You could say that it starts working mostly by accident: you are piggybacking on the synchronization going on in println
.