簡體   English   中英

如何減少Android中的Thread.sleep()延遲

[英]How to Reduce Thread.sleep() Latency in Android

我正在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()的調用。

在上面的示例中,計時變量loopTimeeventTimeeventWait以毫秒為單位測量時間。 測量當前時間的表達式(System.nanoTime() / 100000L)同樣以十分之一毫秒為單位。

我絕對可以肯定, calcutionsTakingVaryingAmountOfTime() 總是少於200毫秒,而對listener.onEvent()的調用只是幾個毫秒。 因此,作為它的立場,與loopTime設置為2500L ,我應該事件每250米的毫秒發生。

我已經插入代碼(未顯示)以將Thread.sleep()喚醒時間中的延遲打印到Log.d() 也就是說,我計算

long latency = (System.nanoTime() / 100000L) - eventTime

Thread.sleep()返回后立即將其打印到Log.d()

當我在模擬器中運行此命令時,發現latency (除以10后將結果轉換為毫微秒)通常在循環的連續遍歷中在1到50毫微秒之間跳躍,偶爾的值會高達半個第二。 當在實際設備上運行時,情況會好很多,但仍然有些不穩定(甚至,仿真器的行為使我懷疑這是否會在用戶的設備上發生)。

為了嘗試穩定事件並控制延遲,我嘗試了其他幾種方法:

  • 在更換Thread.sleep(eventWait / 10L)電話,具有呼叫this.wait(eventWait / 10L)完全不合適的使用wait()的,我知道)

  • 我在進入循環之前操縱了線程優先級,就像在整個Android庫中一樣,調用了Process.setThreadPriority(Process.THREAD_PRIORITY_URGENT_AUDIO)

但是這些延遲根本沒有改善。

一種使事件穩定並使延遲減少到小於2或3毫秒 (很少打h)的方法是用輪詢循環替換Thread.sleep()調用:

while ((System.nanoTime() / 100000L) < eventTime)
    ;

一方面,我感到尷尬地花費了機器周期,就像喝醉了的自由水手一樣。 另一方面,我開始認為沒有更好的方法,我應該在輪詢循環中消耗機器周期,以減少等待時間並符合我的規范。 當然,當我的應用程序進入后台時,我會暫停線程,因此此輪詢循環有效。 但是,真是浪費。

任何想法將不勝感激。

我將Handler延遲消息用於類似目的。 可能有點矯kill過正。 在您的情況下,我將看一下Timer類。

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

這使我在模擬器上的延遲為+ -2毫秒。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM