Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Android中减少Thread.sleep()延迟_Android_Multithreading_Concurrency_Latency - Fatal编程技术网

如何在Android中减少Thread.sleep()延迟

如何在Android中减少Thread.sleep()延迟,android,multithreading,concurrency,latency,Android,Multithreading,Concurrency,Latency,我在Android应用程序中(非UI)线程的循环中生成计时事件,我需要这些事件以精确的时间间隔发生(精确在这里意味着变化不超过+/-5毫秒)。任何+/-10毫秒(当然+/-20毫秒)的误差都可以被用户感知到。在这个循环的顶部,我做了一些其他的计算,这些计算花费了可变的时间,但是在循环的底部,我需要事件在预先计算的时间发生 我的非UI线程的一次尝试的高度简化版本(无异常处理)如下所示: public final void run() { long loopTime = 2500L;

我在Android应用程序中(非UI)线程的循环中生成计时事件,我需要这些事件以精确的时间间隔发生(精确在这里意味着变化不超过+/-5毫秒)。任何+/-10毫秒(当然+/-20毫秒)的误差都可以被用户感知到。在这个循环的顶部,我做了一些其他的计算,这些计算花费了可变的时间,但是在循环的底部,我需要事件在预先计算的时间发生

我的非UI线程的一次尝试的高度简化版本(无异常处理)如下所示:

public final void run() {

    long loopTime = 2500L;
    long eventTime = (System.nanoTime() / 100000L) + loopTime;

    while (true) {

        calcutionsTakingVaryingAmountOfTime(); // takes 200 millisecs or less

        long eventWait = eventTime - (System.nanoTime() / 100000L);
        Thread.sleep(eventWait / 10L);
        listener.onEvent();

        eventTime = eventTime + loopTime;
    }
}
listener.onEvent()
的调用需要精确计时

在上面的示例中,定时变量
loopTime
eventTime
eventWait
以十分之一毫秒为单位测量时间。测量当前时间的表达式
(System.nanoTime()/100000L)
同样以十分之一毫秒为单位

我绝对肯定
calculationVaringamountftime()
所需时间总是少于200毫秒,而调用
listener.onEvent()
只需几毫秒。因此,当
loopTime
设置为
2500L
时,我的事件应该每250毫秒发生一次

我已输入代码(未显示)以打印到
Log.d()
Thread.sleep()中的延迟时间。就是我计算

long latency = (System.nanoTime() / 100000L) - eventTime
Thread.sleep()
返回后立即打印到
Log.d()

当我在模拟器中运行它时,我发现
延迟
(除以10以获得毫秒的结果)通常在循环的连续过程中在1到50毫秒之间跳跃,偶尔值高达半秒。在实际设备上运行时,情况会好一些,但仍然有点不稳定(即使如此,仿真器的行为也让我怀疑这是否会发生在用户的设备上)

为了稳定事件并控制延迟,我尝试了其他几种方法:

  • 在中,将
    Thread.sleep(eventWait/10L)
    调用替换为
    this.wait(eventWait/10L)
    (我知道wait()的用法完全不恰当)

  • 在进入循环之前,我操纵了线程优先级,调用了
    Process.setThreadPriority(Process.thread\u PRIORITY\u emergency\u AUDIO)
    like在所有android库中都是这样做的

但是,这些方法在延迟方面没有任何改善

一种稳定事件、将延迟降低到2或3毫秒以下且很少打嗝的方法是用轮询循环替换
Thread.sleep()
调用:

while ((System.nanoTime() / 100000L) < eventTime)
    ;
while((System.nanoTime()/100000L)
一方面,我觉得像一个醉酒的水手在自由号上骑自行车很尴尬。另一方面,我开始认为没有更好的方法,我应该在轮询循环中燃烧机器周期,以减少延迟,并满足我的规范。当然,当我的应用程序转到后台时,我会暂停线程,这样轮询循环就可以工作了。但这真是浪费


如果您有任何想法,我们将不胜感激。

我将使用带有
处理程序的延迟消息来实现类似目的。这可能有点过分。在你的情况下,我会看一看
定时器

mTimer = new Timer();
mTimer.scheduleAtFixedRate(new TimerTask() {
    @Override
    public void run() {
        Log.v("TEST", " tick");
    }
}, 0, 250);

这给了我emulator的延迟+-2毫秒。

谢谢你的建议。我试过几件事。首先,我尝试使用对“java.util.Timer.schedule(TimerTask,long delay)”的调用(或多或少)替代对“Thread.sleep()”的调用。我对你的建议有点怀疑。我试过几件事。首先,我尝试使用对“java.util.Timer.schedule(TimerTask,long delay)”的调用(或多或少)替代对“Thread.sleep()”的调用。然后我试着使用“scheduleAtFixedRate()”,就像你的一样。在这两种情况下,我在emulator上都有1到70毫秒的延迟,尽管延迟几乎符合设备的规格。你还做了什么来在模拟器上获得+/-2毫秒的延迟?我只运行了一个很小的测试应用程序,所以几乎没有压力。我的CPU是Intel(R)Core(TM)2 Duo CPU T9300@2.50GHz。谢谢回复。“这对我很有用。”歌词:我和你有同样的问题
Thread.sleep()
破坏了我的应用程序,因为我还有和你描述的一样大的延迟。但是您是如何使用
计时器模拟
线程.sleep
?你已经找到更好的解决方案了吗?