首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用nanoTime()循环

用nanoTime()循环
EN

Stack Overflow用户
提问于 2014-08-07 13:26:28
回答 2查看 762关注 0票数 0

我想和下面的代码一样,但是使用System.nanoTime()代替

代码语言:javascript
复制
new Timer().schedule(new TimerTask()
            {
                public void run()
                {
                    bt.send("Start");

                    try {
                        Thread.currentThread().setPriority(1);
                        Thread.sleep(50, 0);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }


                    s.playSound();
                }           }
            , 0, 3000);

其思想是在3秒的send()周期间隔中,一个接一个地运行(在运行send()后50毫秒),运行和playSound() 两种方法。我想使用nanoTime()的原因是计时器不准确,播放安卓设备的音频也有一些延迟,而我也在寻找时间的准确性和精确性。我也尝试过在单独的线程中执行,但是仍然有很多延迟。所以我试着把代码修改成这样:

代码语言:javascript
复制
    long t1=System.nanoTime();
            long t = t1;
            while(true)
            {
                long t2 = System.nanoTime();
                if(t2>=t1+3 seconds)
                    bt.send("Start");
                t1=t2;
                t3=System.nanoTime();
                if(t3>=t+3500 milliseconds)
                    playsound();
                t=System.nanoTime();
            }

当然,它不起作用。有谁可以帮我?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-08-07 14:04:11

我不知道您是从哪里想到使用while(true)的,但这是行不通的。通常,整个代码块都无法工作。

您的原始代码有正确的想法,使用Timer。但是,如果需要,也可以使用Handler。但我必须告诉你:准确地选择这样的时间几乎是不可能的,你必须小心对待nanoTime()。在普通智能手机上,没有任何系统能够测量几纳秒的时差。即使毫秒也可能是不准确的。

总之,1纳秒= 0.000000001秒。我高度怀疑,你需要的时间是如此精确。仅仅使用nanoTime()并不能为测量增加任何准确性,只是更有可能出现不准确的情况。

我的观点是:最初的代码几乎完全正确,我严重怀疑Timer是否如此不准确。很可能您只是认为它是不准确的,因为其他一些无关的编程错误。

我稍微修改了您的代码,以测试其准确性,这是我使用的代码:

代码语言:javascript
复制
new Timer().schedule(new TimerTask() {
    public void run() {
        long start = System.currentTimeMillis();
        try {
            Thread.sleep(50, 0);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        long end = System.currentTimeMillis();

        final long pause = end - start;
        final long interval = start - lastStartup;
        lastStartup = start;
        Log.i("Timing Tests", interval + " / " + pause);
    }
}, 3000, 3000);

这些是我得到的结果:

代码语言:javascript
复制
Timing Tests﹕ 3000 / 50
Timing Tests﹕ 3000 / 51
Timing Tests﹕ 3000 / 50
Timing Tests﹕ 3000 / 50
Timing Tests﹕ 3000 / 50
Timing Tests﹕ 3000 / 50
Timing Tests﹕ 3000 / 51
Timing Tests﹕ 3000 / 50
Timing Tests﹕ 3000 / 50
Timing Tests﹕ 3000 / 50
Timing Tests﹕ 3000 / 50
Timing Tests﹕ 3001 / 50
Timing Tests﹕ 3000 / 50
Timing Tests﹕ 3001 / 50
Timing Tests﹕ 3000 / 50
Timing Tests﹕ 3000 / 51
Timing Tests﹕ 3000 / 50
Timing Tests﹕ 3000 / 50
Timing Tests﹕ 3000 / 50
Timing Tests﹕ 3001 / 50
Timing Tests﹕ 3000 / 50
Timing Tests﹕ 3000 / 50
Timing Tests﹕ 3001 / 50
Timing Tests﹕ 3000 / 50
Timing Tests﹕ 3000 / 50

换句话说,Timer精确到+-1ms。这是非常准确的,不仅在Android上,而且在任何操作系统上都是如此。这是如此准确,以至于没有一个用户会注意到这个微小的差别。

所以我想我要说的是:您的代码已经尽可能准确了。如果您有计时问题,那么它们与TimerTimerTask无关。

票数 1
EN

Stack Overflow用户

发布于 2014-08-07 14:35:57

就是这里

代码语言:javascript
复制
public void sleep(long millis, long nanos) throws InterrupedException {
    long start = System.nanoTime();
    long duration = millis*1000000 + nanos;
    while (System.nanoTime()-start<duration) {
        long remaining = duration - System.nanoTime() + start;
        Thread.sleep(remaining/1000000, remaining%1000000);
    }
}

和周期性的召唤

代码语言:javascript
复制
while (!isCancelled()) {
    long start = System.nanoTime();
    send("Start");

    long toSleep = TimeUnit.NANOSECONDS.convert(50, TimeUnit.MILLISECONDS) - System.nanoTime() + start;
    sleep(toSleep/1000000, toSleep%1000000);
    s.playSound();

    toSleep = TimeUnit.NANOSECONDS.convert(3, TimeUnit.SECONDS) - System.nanoTime() + start;
    sleep(toSleep/1000000, toSleep%1000000);
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25183807

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档