2017-05-07 87 views
1

我一直在測試android中的一些asynctasks。在AsyncTask中嵌套/正常for循環

但我發現有些不合邏輯的結果對這些代碼:

int a1Sum = 0; 
int a2Sum = 0; 

long a1Time = 0; 
long a2Time = 0; 

private class Async1 extends AsyncTask<Void, Void, String> { 
    protected void onPreExecute() { 
     a1Time = System.currentTimeMillis(); 
    } 

    protected String doInBackground(Void... arg0) { 
     for (int i = 0; i < 10000; i++) { 
      publishProgress(); 
     } 
     return "You are at PostExecute"; 
    } 

    protected void onProgressUpdate(Void... arg0) { 
     a1Sum++; 
    } 

    protected void onPostExecute(String result) { 
     Log.d("A1 Time", String.valueOf(System.currentTimeMillis() - a1Time)); // records the executing time 
     AsyncTask async2 = new Async2().execute(); 
    } 
} 

private class Async2 extends AsyncTask<Void, Void, String> { 
    protected void onPreExecute() { 
     a2Time = System.currentTimeMillis(); 
    } 

    protected String doInBackground(Void... arg0) { 
     for (int i = 0; i < 10; i++) { 
      for (int j = 0; j < 10; j++) { 
       for (int k = 0; k < 10; k++) { 
        for (int l = 0; l < 10; l++) { 
         publishProgress(); 
        } 
       } 
      } 
     } 
     return "You are at PostExecute"; 
    } 

    protected void onProgressUpdate(Void... arg0) { 
     a2Sum++; 
    } 

    protected void onPostExecute(String result) { 
     Log.d("A2 Time", String.valueOf(System.currentTimeMillis() - a2Time)); // records the executing time 
    } 
} 

這兩個asynctasks做同樣的工作,但這裏是不合邏輯的部分:

,你在代碼中看到,a1Timea2Time記錄執行時間,這裏是他們的結果:

D/A1 Time: 1025 
D/A2 Time: 768 
D/A1 Time: 1022 
D/A2 Time: 716 
D/A1 Time: 1017 
D/A2 Time: 729 
D/A1 Time: 1063 
D/A2 Time: 830 
D/A1 Time: 1059 
D/A2 Time: 784 

我的問題是:是什麼讓Async2跑得快嗎?

+0

@ Kaushal28但不應該'Async1'更快,因爲它更簡單? –

+0

有趣。現在轉身。讓線程1由線程2啓動。 – greenapps

+0

如果'''''''''''''''''''''''''''''''''Async2''的實現和Aynsc1'完全相同,它會以相同的方式結束結果還是會有相同的執行時間?當代碼在主UI線程和後臺線程之間切換時會更好地剖析執行時間,這會增加開銷,因此需要跟蹤doInBackground()實現的時間。我認爲他們會以接近的執行時間結束。最後,(我可能要求太多,道歉),如果使用'executeOnExecutor(THREAD_POOL_EXECUTOR)''而不是''execute()''',它會一樣嗎? – ahasbini

回答

2

正如註釋的發現結果的回顧一下,測試結果如下(請注意,AsyncTasks並行順序和不執行):

通過Async2執行Async1導致與同一執行時間。這隻能通過操作系統優化執行來推理,但在其他情況下,例如不同設備或甚至執行測試的不同時間,測試結果可能會有所不同。

使用executeOnExecutor(THREAD_POOL_EXECUTOR)執行任務而不是​​導致執行時間相同。這可能是由於操作系統立即啓動後臺線程的想法,因此,既然計算相同數量的循環,執行時會有細微的差異,他們最終會得到類似的執行時間。

進一步的解剖仍然是需要的,它只計時doInBackground()實現爲了計算在主UI線程和後臺線程之間切換的開銷。

+1

顯得相當可接受,再加上一個 – Kaushal28

1

您的2 nd線程不慢,但是您的兩個線程都按照連續順序運行。對於Asynctasks,如果兩個線程同時啓動,那麼它們將默認以串行順序運行。如評論AnsncTask.executeOnExector(AsyncTask.THREAD_POOL_EXECUTOR)中所述,將強制兩個asyncTasks並行運行。請參閱以下更多的執行順序:This answer

當它們並行運行時,它們將顯示相同的計數。你的結果的差異是因爲每個線程執行函數的複雜性。

+0

感謝您將它封裝起來,但爲什麼通過'Async2'執行'Async1'給出相同的執行時間? –

+0

@BedrockDev它的666和668的權利? – Kaushal28

+0

它的649和656(by @greenapps) –