Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 7: IF condition triggered when false

I have this piece of code:

void timerCountDown(){
    while(RaftNode.getTimeoutVar()){
        long x = System.currentTimeMillis();
        if(x >= RaftNode.limit){
            System.out.println(x);
            System.out.println(RaftNode.limit + " THIS SHOULD BE LESS THAN");
            System.out.println(System.currentTimeMillis() + " THIS");
            System.out.println("TIMED OUT");
            raft.RaftNode.setTimeoutVar(false);
            nextRandomTimeOut();
            raft.RaftNode.onTimeOut();
        }
    }
}

So basically, this is a time-out function and the time-out is refreshed by another condition. My issue is that the x >= RaftNode.limit condition keeps triggering even though it is false (through the print statements).

My console outputs:

1431532870542
1431532872508 THIS SHOULD BE LESS THAN
1431532870542 THIS

So x is indeed the current time, but even though it is less than the limit, the condition is being triggered.

I have no idea why!

The limit var is

public static long limit;

so nothing fancy here

like image 828
dan Avatar asked Oct 31 '22 04:10

dan


2 Answers

It can only be a problem using threads. The update of the values of a shared variable can be delayed. Make limit volatile or so.

It is basically a threading issue, a search on java volatile will point further. Rather silly but threads can have stale values of some variable altered by another thread. With volatile the compiler ensures with extra code that threads get updated values. That variable values are copied into a thread might be considered an optimization issue. But then look at JIT too, LL2 cache and so on.

(started as comments.)

like image 115
Joop Eggen Avatar answered Nov 04 '22 12:11

Joop Eggen


Could you try something like the following?

void timerCountDown(){
    long limit = RaftNode.limit;
    long raft_time = RaftNode.getTimeoutVar();
    long x = System.currentTimeMillis();

    while(raft_time){
        x = System.currentTimeMillis();
        if(x >= limit){
            System.out.println(x);
            System.out.println(limit + " THIS SHOULD BE LESS THAN");
            System.out.println(x + " THIS");
            System.out.println("TIMED OUT");
            raft.RaftNode.setTimeoutVar(false);
            nextRandomTimeOut();
            raft.RaftNode.onTimeOut();
        }
        raft_time=RaftNode.getTimeoutVar();
    }
}
like image 43
Christian Sarofeen Avatar answered Nov 04 '22 10:11

Christian Sarofeen