Reliable cross-platform method for getting a method in Java

This question is not about the benchmark.

I have a java cycle loop that should work close to the T time period:

public class MyRunnable implements Runnable {

    private final long period = 10000L; //period T, in this case 10 secs

    public void run() {
        while() {
            long startTime = this.getTime();

            long endTime = this.getTime();
            this.doStuff();
            long executionTime = endTime - startTime;
            if(executionTime < this.period) {
                long sleepTime = (this.period - executionTime);
                try {
                     Thread.sleep(sleepTime);
                } catch(InterruptedException iex) {/*handle iex*/}
            }
        }
    }

    private long getTime() {
        return System.currentTimeMillis();
    }

    private void doStuff() {/*do stuff*/}

} 

Of course, depending on the choice of the schedule, the schedule Thread.sleep(sleepTime)may be slightly larger sleepTime. But on average, this approach provides a close averaged approximation to period T.

Problem

Method:

private long getTime() {
    return System.currentTimeMillis();
}

provides the wall reference hours of time. If the machine clock changes forward or backward, this implementation does not provide a close approximation for period T. For example:

long t1 = getTime();
Thread.sleep(30000);
long t2 = getTime();
System.out.println(t2 - t1);

it displays something like 204283 if someone manually changes the clock three minutes ahead, but Thread.sleep(30000)"works."

( , , ..) System.currentTimeMillis() .

, getTime:

long getTime() {
    long result;
    ThreadMXBean mxBean = ManagementFactory.getThreadMXBean();
    if (mxBean.isThreadCpuTimeSupported()) {
        result = mxBean.getCurrentThreadCpuTime()/1000000L;
    } else {
        throw new RuntimeException("unsupported thread cpu time");
    }
    return result;
}

getCurrentThreadCpuTime , - , , . , , . :

long t1 = getTime();
Thread.sleep(30000);
long t2 = getTime();
System.out.println(t2 - t1);

"0" () getCurrentThreadCpuTime getTime.

, - :

private long getTime() {
    long cpuCycles = getAmountOfCPUCyclesSinceTheProgramStarted();
    long cpuFrequency = getCPUFrequency();
    long result = cpuCycles / cpuFrequency;
    return result;
}

, java- getAmountOfCPUCyclesSinceTheProgramStarted() getCPUFrequency() - .

, : java - ?

+4
1

System.nanoTime(), , .

:

- .

+4

Source: https://habr.com/ru/post/1691474/


All Articles