在Java程序中
我们可以用System
currentTimeMillis()来计时
但是精度不高
在我的机子(Pentium M
GHz
WinXP)上
精度小于
ms
通过一个简单的Java程序
我们可以测试
publicstaticvoidmain(String[]args){
longbegin=SystemcurrentTimeMillis();
longcurrent;
while(begin==(current=SystemcurrentTimeMillis()))
;
Systemoutprintln((currentbegin)+ms);
}
SystemcurrentTimeMillis()大约ms才变化一次
ms的精度在很多情况下是不够用的比如开发射击类游戏等等而PC中自身计时器的精度要高很多即使是WindowsXP提供的计时器也要比Java的SystemcurrentTimeMillis()高太多了比如用Win的QueryPerformanceCounter函数在我的机子上可以得到ns的精度计算机越发展软件利用硬件的程度和效率却越来越差这一点在Java的身上表现的尤其严重随着多核CPU的普及这个问题还要进一步严重
言归正传我们来讲怎么利用QueryPerformanceCounter来实现一个native的Java计时器
packagecnpandaoentimer;
/**
*ATimerclassusesnativemethodstomeasuretimes
*
*@authorpan
*/
publicclassTimer{
privatelongprev;
publicvoidreset(){
prev=QueryPerformanceCounter();
}
/**
*@returnthedurationinmsfromthepointofreset()
*/
publicdoublegetDuration(){
longcurrent=QueryPerformanceCounter();
return(currentprev)/frequency;
}
staticfinaldoublefrequency;
staticnativelongQueryPerformanceFrequency();
staticnativelongQueryPerformanceCounter();
static{
SystemloadLibrary(extension);
frequency=QueryPerformanceFrequency()/;
}
}
Native的代码
#includecn_pandaoen_timer_Timerh
#include<windowsh>
JNIEXPORTjlongJNICALL
Java_cn_pandaoen_timer_Timer_QueryPerformanceFrequency(JNIEnv*ejclasscls)
{
LARGE_INTEGERfrequency;
QueryPerformanceFrequency(&frequency);
return(jlong)frequencyQuadPart;
}
JNIEXPORTjlongJNICALL
Java_cn_pandaoen_timer_Timer_QueryPerformanceCounter(JNIEnv*ejclasscls)
{
LARGE_INTEGERcounter;
QueryPerformanceCounter(&counter);
return(jlong)counterQuadPart;
}
用法是在开始点调用的timerreset() 结束时调用timergetDuration()得到所用的时间单位是ms一个timer的instance可以多次使用
下面我们来看看这个计时器都多高的精度
publicclassTimerTest{
publicstaticvoidmain(String[]args) {
longf=TimerQueryPerformanceFrequency();
longp=TimerQueryPerformanceCounter();
longc;
while(p==(c=TimerQueryPerformanceCounter()))
;
Systemoutprintln(((cp)*/f)+ns);
}
}
在同样的系统下我得到ns的精度
这种方法的一个缺点当然是它现在还只能在Windows下使用如果有朋友愿意帮忙实现别的系统下的native代码的话我会非常感谢的