簡體   English   中英

可靠的跨平台方式在Java中獲取方法時間

[英]Reliable cross-platform way to obtain the method time in Java

這個問題與基准無關。

我有一個java線程周期,應該在接近周期時間T操作:

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();

            this.doStuff();

            long endTime = this.getTime();
            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*/}

} 

當然,根據計划預設選擇, Thread.sleep(sleepTime)可能略大於sleepTime 但是,平均而言,這種方法提供了與周期T的近似平均近似值。

問題

方法:

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

提供掛鍾參考時間。 如果機器的時鍾向前或向后變化,則此實現無法提供T期間的近似值。例如:

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

如果有人在Thread.sleep(30000) “運行”的情況下提前三分鍾手動更改時鍾,則打印類似204283的內容。

由於使用System.currentTimeMillis()的系統時鍾總是在變化(時間服務器同步,系統負載,用戶設置等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的問題是得到的時間量是線程消耗的CPU時間,而不是該時刻剩余的時間。 線程處於休眠狀態或被阻止時的剩余時間未考慮在內。 例如:

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

令人驚訝的是, getCurrentThreadCpuTime getTime的實現打印出“0”(零)。

我想要的是

我想我需要的是這樣的:

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

問題是我沒有找到一種java方式以跨平台的方式實現getAmountOfCPUCyclesSinceTheProgramStarted()getCPUFrequency()

最后,我的問題是:如何以可靠和跨平台的方式獲取java中方法的花費時間?

嘗試使用System.nanoTime() ,它似乎是你正在尋找的。

來自文檔:

此方法只能用於測量經過的時間,與系統或掛鍾時間的任何其他概念無關。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM