Welcome to FutureAppLaboratory

v=(*^ワ^*)=v

AsyncTask同士は非同期実行

| Comments

AsyncTaskはなに?

http://developer.android.com/reference/android/os/AsyncTask.html

  • AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.

ほんとに非同期なの?

AsyncTaskはUIThreadと非同期処理を行うが、AsyncTask同士の間ではデフォルトで同期的に行っているみたいね。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
 private class TestTask extends AsyncTask<Void, Void, Void> /* Params, Progress, Result */ {

    private final int id;
    private final int duration;

    TestTask(int id, int duration) {
        this.id       = id;
        this.duration = duration;
    }

    @Override
    protected Void doInBackground(Void... params) {
        int taskExecutionNumber = executedTasksCount.incrementAndGet();
        log("doInBackground: entered, taskExecutionNumber = " + taskExecutionNumber);
        SystemClock.sleep(duration); // emulates some job
        log("doInBackground: is about to finish, taskExecutionNumber = " + taskExecutionNumber);
        return null;
    }

    private void log(String msg) {
        Log.d("TestTask #" + id, msg);
    }
}

// ===========================

for (int i = 0; i < numberOfTasks; i++) {
    int taskId = i + 1;
    int taskDuration = 1000; // 1000 ms
    TestTask task = new TestTask(taskId, taskDuration);

    // デフォルトでは同期処理。
    // task.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR) が実行される。
    task.execute();
}

結果。順番待ちですね。

result_1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
for (int i = 0; i < numberOfTasks; i++) {
    int taskId = i + 1;
    int taskDuration = 1000; // 1000 ms
    TestTask task = new TestTask(taskId, taskDuration);

    // こう書くと、非同期実行になる
    // ソース(sdk v.21)を見ると、並列実行ができるExecutorで処理されるぽい
    task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}

// ========================
// 以下はAsyncTask.THREAD_POOL_EXECUTORの正体。
// androidのソースから抜いた
// ========================

private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
private static final int CORE_POOL_SIZE = CPU_COUNT + 1;
private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
private static final int KEEP_ALIVE = 1;

private static final ThreadFactory sThreadFactory = new ThreadFactory() {
    private final AtomicInteger mCount = new AtomicInteger(1);

    public Thread newThread(Runnable r) {
        return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());
    }
};

private static final BlockingQueue<Runnable> sPoolWorkQueue =
        new LinkedBlockingQueue<Runnable>(128);

/**
 * An {@link Executor} that can be used to execute tasks in parallel.
 */
public static final Executor THREAD_POOL_EXECUTOR =
    new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);

結果。非同期になった!

結果2

因みに、同時に処理できるスレッドの数は、CORE_POOL_SIZEに定義されている。sdk v21の場合、CPUのコア数+1になっている。
私のテスト端末はクアッドコアなので、同時に5つ走らせる。

それ以上走らせると、やっはり順番待ちになるのね。

結果3

Comments