我已经在android中测试了一些asynctasks。

但是我在这些代码上发现了一些不合逻辑的结果:

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
    }
}


这两个异步任务执行相同的工作,但这是不合逻辑的部分:

如您在代码上看到的,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运行更快?

最佳答案

作为对评论中发现的结果的回顾,测试结果如下(请注意,AsyncTasks是按顺序而不是并行执行的):

Async1执行Async2会导致执行时间相同。这只能通过OS的执行优化来推断,但是在其他情况下(例如不同的设备或什至在执行测试的时间不同),测试的结果可能会有所不同。

使用executeOnExecutor(THREAD_POOL_EXECUTOR)而不是execute()执行任务导致执行时间相同。这可能是由于OS立即启动后台线程的想法造成的,因此,由于两者都计算出相同数量的循环,执行上的差异很小,因此它们将以相似的执行时间结束。

仍然需要进一步的剖析,即仅对doInBackground()实现进行计时,以计算出在主UI线程和后台线程之间进行切换的开销。

08-05 15:49