需要评估某个程序运行消耗的时间时,一般情况下在JAVA中使用System.currentTimeMillis()来记录当前的时间,运行后再次采集一次当前时间,将两者的差作为运行消耗的时间。但这个时间并不是十分的精确,因为在程序运行的过程中,可能发生系统进程切换等系统事件,这部分时间也被计算在这个消耗时间里。
而Java 虚拟机实现可能提供了支持测量当前线程的 CPU 时间的功能。ThreadMXBean接口提供了线程时间管理、争用监视等功能,使用前应先确定该JDK实现,提供了这方面的功能。isThreadCpuTimeSupported() 方法可以用于确定 Java 虚拟机是否支持测量任何线程的 CPU 时间。isCurrentThreadCpuTimeSupported() 方法可以用于确定 Java 虚拟机是否支持测量当前线程的 CPU 时间。支持任何线程 CPU 时间测量的 Java 虚拟机实现也支持当前线程的 CPU 时间测量。通过调用 ManagementFactory.getThreadMXBean() 方法获得ThreadMXBean的实现。
封装的获取时间的方法 :
/** Get CPU time in nanoseconds. */
public static long getCpuTime () {
ThreadMXBean bean = ManagementFactory.getThreadMXBean();
return bean.isCurrentThreadCpuTimeSupported() ? bean
.getCurrentThreadCpuTime() : 0L;
}
/** Get user time in nanoseconds. */
public static long getUserTime () {
ThreadMXBean bean = ManagementFactory.getThreadMXBean();
return bean.isCurrentThreadCpuTimeSupported() ? bean
.getCurrentThreadUserTime() : 0L;
}
测试例子:
Thread t1 = new Thread(new Runnable() {
@Override
public void run () {
try {
for (;;) {
long start = getUserTime();
//long start = System.currentTimeMillis();
System.out.println("T1 Start: " + start);
for (int i = 0; i < 900000000; i++) {
for (int j = 0; j < 10000000; j++) {
}
}
Thread.sleep(2);
long now = getUserTime();
// long now = System.currentTimeMillis();
System.out.println("T1 End: " + now);
System.out.println("Thread 1, const(milli Sec): "
+ (now - start) / 1000000);
Thread.sleep(2000);
}
}
catch (Exception e) {
e.printStackTrace();
}
}
});
Thread1会定期输出两个for循环所消耗的时间。
Thread t2 = new Thread(new Runnable() {
@Override
public void run () {
try {
boolean runned = false;
for (;;) {
long start = getUserTime();
System.out.println("T2 Start: " + start);
// if (!runned) {
// for (int i = 0; i < 900000000; i++) {
// for (int j = 0; j < 10000000; j++) {
// }
// }
// runned=true;
// }
Thread.sleep(500);
long now = getUserTime();
System.out.println("T2 End: " + now);
System.out.println("Thread 2, const(milli Sec): "
+ (now - start) / 1000000);
}
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread2 输出的T2 Start、T2 End永远都是0。因为Thread2 只是暂停了线程,并没有做任何逻辑运算,因此这个线程实际上并没有占用时间。