I'm just testing some concurrent programming in Java. Basically I have a class (Light) which is a kind of finite state machine, and changing its state regarding the commands. That's what I'm trying to: The light is in ON state, I send a command to the thread of this class for changing the state in OFF. But I got a problem during the execution.
First, let me present the class:
enum State {ON, OFF}; 
public class Light implements Runnable {
private boolean cmdOn;
private boolean cmdOff;
State state;
public Light() {
    cmdOn = false;
    cmdOff = false;
    state = State.ON;
}
@Override
public void run() {
    while(true) {
        switch(state) {
        case ON:
            if(cmdOff) {
                try {
                    Thread.currentThread().sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                state = State.OFF;
            }
            break;
        case OFF:
            if(cmdOn) {
                try {
                    Thread.currentThread().sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                state = State.ON;
            }
            break;
        }
    }
}
public void setCmdOn(boolean cmdOn) {
    this.cmdOn = cmdOn;
}
public void setCmdOff(boolean cmdOff) {
    this.cmdOff = cmdOff;
}
public State getState() {
    return state;
}
}
And my main class:
public class Main {
public static void main(String args[]) throws InterruptedException {
    Light light = new Light();
    Thread t = new Thread(light);
    t.start();
    printState(light, 500, 1);
    light.setCmdOff(true);
    printState(light, 500, 4);
}
public static void printState(Light l, int time, int number) throws InterruptedException {
    for(int i= 0; i < number; i++) {
        System.out.println(l.getState());
        Thread.currentThread().sleep(time);
    }
}
The output shows me that I'm stuck in the ON state while I should be in OFF state.
In a second run, after putting an instruction (System.out.println or whatever...) above the if statement which verify that cmdOff is true, it's magically works.
I don't understand why the cmdOff variable is not pass to true during the first run !?
And why in the second run it works?
I miss something, probably a synchronizing block. But I don't find the explanation to deal with this.
Thanks.
Best regards,
 
     
     
     
     
    