简体   繁体   中英

Thread.join(millisecond) is not accuracy in java?

As we all know in java, Thread.join(long millis) means "Waits at most millis milliseconds for this thread to die", but i find the millisecond is not very accuracy, please see the following code:

public class MyThreadTest {
public void invokeTest() {
    long executionTimeLimit = 10;
    Runner rn = new Runner();
    rn.start();
    try {
        long time = System.currentTimeMillis();
        rn.join(executionTimeLimit);
        long l1 = (System.currentTimeMillis() - time);
        System.out.println("execution_time_limit="+executionTimeLimit+" the invoke method time is "+l1+" millisecond");
    } catch (Exception e) {
        //e.printStackTrace();
    }
}
public static void main(String args[]) {
    MyThreadTest mtt = new MyThreadTest();
    mtt.invokeTest();
}
private final class Runner extends Thread {
    public void run()
    {
        //to make the program a bit longer
        int size = 3000;
        String[][] bb = new String[size][size];
        for(int i=0;i<size;i++) 
            for(int j=0;j<size;j++) {
                bb[i][j] = "bbbbbbbbbbb";
        }

    }
}
}

the output log is not same when you running more than one times:

"execution_time_limit=10 the invoke method time is 11 millisecond" "execution_time_limit=10 the invoke method time is 32 millisecond" "execution_time_limit=10 the invoke method time is 34 millisecond"

why does that happen?

When you wait(n) or sleep(n) and it is not interrupted or notify()ed, it waits for at least the time given. In join(n) both is possible. It wakes early on a notify/end of thread, but can wake at any time after that.

The variation is between when a thread could wake and when it does wake is so wide there are tools which monitor such things. jHiccup being one of the best.

When a thread wakes up is dependant onload, but also the OS. This can lead to threads waking long after they should. A recent question for MacOS concerned delays of up to 10 second delay for a idle system.

This is something Java has no control over, it is down to your OS.

BTW if you look at jitter on the micro-second level you see much more colourful variations/jitter/interrupts of processes.

Micro jitter, busy waiting and binding CPUs

When we deal with threads, we can never ensure the time accuracy as these operations like wait, join, sleep are also dependant on system resources' availability.

Check Oracle tutorials http://docs.oracle.com/javase/tutorial/essential/concurrency/join.html

The doxygen is just confusing you, because it says "Waits at most millis milliseconds for this thread to die".

The join() function just allows the calling thread to "wait for a while" rather than stuck forever. When the join() function returns, the thread you called it on might still be running (ie it didn't "joined"). In this case join() would have waited for at least millis milliseconds, then that thread didn't finish and join() gave up. On the other hand, if the thread join() has been called on did actually finish than join() would have waited for less than millis milliseconds.

Bear also in mind that unless you're JVM is running on a Real Time Operating System (and those threads have certains priorities), other processes/threads can be scheduled causing join() return to be delayed even longer (which happened when you've got 34ms rather than 11ms).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM