网站首页
JSP空间
动态资讯
开源项目
技术文档
资源下载
J2EE资源
客户论坛
在线支付
 
  技术文档>>JAVA>>新手入门>>基础入门>查看文档  
  用jni实现一个高精度的java计时器     
  文章作者:未知  文章来源:水木森林  
  查看:89次  录入:管理员--2007-11-17  
      在java程序中,我们可以用system.currenttimemillis()来计时,但是精度不高,在我的机子(pentium m 1.5ghz, winxp)上,精度小于10ms。通过一个简单的java程序,我们可以测试


code highlighting produced by actipro codehighlighter (freeware)
http://www.codehighlighter.com/

-->public static void main(string[] args) {
        long begin = system.currenttimemillis();
        long current;
        while (begin == (current = system.currenttimemillis()))
            ;
        system.out.println((current - begin) + " ms");
}

system.currenttimemillis()大约10ms才变化一次。

   10ms的精度在很多情况下是不够用的,比如开发射击类游戏等等。而pc中自身计时器的精度要高很多,即使是windowsxp提供的计时器也要比java的system.currenttimemillis()高太多了。比如用win32的queryperformancecounter函数,在我的机子上可以得到1ns的精度。计算机越发展,软件利用硬件的程度和效率却越来越差,这一点在java的身上表现的尤其严重,随着多核cpu的普及,这个问题还要进一步严重。

言归正传,我们来讲怎么利用queryperformancecounter来实现一个native的java计时器.

code highlighting produced by actipro codehighlighter (freeware)
http://www.codehighlighter.com/

-->package cn.pandaoen.timer;

/**
 * a timer class uses native methods to measure times.
 *  
 * @author pan
 */
public class timer {

    private long prev;

    public void reset() {
        prev = queryperformancecounter();
    }

    /**
     * @return the duration in ms from the point of reset()
     */
    public double getduration() {
        long current = queryperformancecounter();
        return (current - prev) / frequency;
    }

    static final double frequency;

    static native long queryperformancefrequency();

    static native long queryperformancecounter();

    static {
        system.loadlibrary("extension");
        frequency = queryperformancefrequency() / 1000.0;
    }
}

native的代码

code highlighting produced by actipro codehighlighter (freeware)
http://www.codehighlighter.com/

-->#include "cn_pandaoen_timer_timer.h"
#include <windows.h>

jniexport jlong jnicall
java_cn_pandaoen_timer_timer_queryperformancefrequency(jnienv *e, jclass cls)
{
    large_integer frequency;
    queryperformancefrequency(&frequency);
    return (jlong)frequency.quadpart;
}

jniexport jlong jnicall
java_cn_pandaoen_timer_timer_queryperformancecounter(jnienv *e, jclass cls)
{
    large_integer counter;
    queryperformancecounter(&counter);
    return (jlong)counter.quadpart;
}

用法是,在开始点调用的timer.reset(), 结束时调用timer.getduration()得到所用的时间,单位是ms.一个timer的instance可以多次使用.

下面我们来看看这个计时器都多高的精度。

code highlighting produced by actipro codehighlighter (freeware)
http://www.codehighlighter.com/

-->public class timertest {
    public static void main(string[] args) {
        long f = timer.queryperformancefrequency();
        long p = timer.queryperformancecounter();
        long c;
        while (p == (c = timer.queryperformancecounter()))
            ;
        system.out.println(((c - p) * 1000000 / f) + " ns");
    }
}
在同样的系统下,我得到1ns的精度.

这种方法的一个缺点当然是,它现在还只能在windows下使用,如果有朋友愿意帮忙实现别的系统下的native代码的话,我会非常感谢的。
 
 
上一篇: swt中模拟awt的borderlayout    下一篇: struts标签使用举例--logic篇
  相关文档
struts源码研究-bean-message标签篇 11-17
java初学者实践教程25-多线程 11-17
商业周刊:开发工具大战java进退维谷 11-16
结合ms ajax将js文件编译到动态链接库 11-17
深入浅析tomcat配置技巧 top 10 11-17
在java程序中运行外部类文件 11-17
java多线程编程基础之线程和多线程 11-17
爪哇语言观察者模式介绍 11-17
网上选课系统.java 11-17
javatm studio creator 入门 11-17
在struts中使用plugin扩展hibernate 03-24
让所有初学者明白 java 程序的结构 11-17
eclipse中报错的解决方案 11-17
java读取文件中含有中文的解决办法 11-17
jini技术介绍(二) 11-16
javascript中最流行的2种定义类的方式 12-26
j2se综合:对java.util的总结九 11-17
使用 xmlhttprequest 编程原文章和注意事项 11-17
java动态代理实现aop 11-17
java基础: 在java程序中调用其他程序 11-16
返回首页 | 关于我们 | J网章程 | JSP空间合租 | 客服中心 | 免责声明 | 常见问题 | 参观机房
本站主机空间代理至厦门市华众网络科技有限公司
《中华人民共和国增值电信业务经营许可证》
编号:闽B2-20050079
@2005-2008福建JSP技术网 版权所有 闽ICP备05000928号
厦门(总部):13616026886 福州:0591-87655121
邮箱:admin@fjjsp.com 站长QQ,点击这里给我发消息