java

位置:IT落伍者 >> java >> 浏览文章

用JNI实现一个高精度的Java计时器


发布日期:2024年03月02日
 
用JNI实现一个高精度的Java计时器
在Java程序中我们可以用SystemcurrentTimeMillis()来计时但是精度不高在我的机子(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代码的话我会非常感谢的               

上一篇:利用Socket进行Java网络编程(三)

下一篇:Java连接各种数据库的实例