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)
"runs".
时手动将时钟提前三分钟更改,则打印类似 204283 的内容
由于系统时钟总是在变化(时间服务器同步、系统负载、用户设置等),使用 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()
,它似乎就是您要找的。
来自 the docs:
This method can only be used to measure elapsed time and is not related to any other notion of system or wall-clock time.
此问题与基准无关。
我有一个 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)
"runs".
由于系统时钟总是在变化(时间服务器同步、系统负载、用户设置等),使用 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()
,它似乎就是您要找的。
来自 the docs:
This method can only be used to measure elapsed time and is not related to any other notion of system or wall-clock time.