2017-05-07 85 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) –