행복한 가족, 패밀리그램

개발/안드로이드

AsyncTask 에 대하여 #2. 스케쥴링 ThreadPool

패밀리그램 2016. 12. 5. 23:23

AsyncTask 에 대하여 #1. 간단한 설명


위 포스팅에서 설명했던 간단한 AsyncTask에 대한 동작외에 실제로 AsyncTask가 동작되는 ThreadPool에 대해

간단하게 알아보려고 한다.


AsyncTask.java 소스를 살펴보면 클래스 변수 중에 아래와 같은 변수를 볼 수 있다.


private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
 
 
cs


224 라인에 위와 같이 선언되어 있다.

(Android SDK 버전에 따라 코드라인이 다를 수 있다.)


SERIAL_EXECUTOR 가 기본 ThreadExecutor 이다 . 여기서 Executor는 AsyncTask Thread를 관리해 주는 ThreadPool 정도로 생각하면된다.


단어 뜻 그대로 Serial이다. AsyncTask를 여러 개 실행 시킨다면 실행되는 순서대로 실행 시켜준다는 뜻이다.


1
2
3
4
    DownloadFilesTask task1 = new DownloadFilesTask();
    DownloadFilesTask task2 = new DownloadFilesTask();
    task1.execute("http://....");
    task2.execute("http://....");
cs


이 전 포스팅에서 정의하였던 DownloadFileTask 객체를 2개 생성하여 실행 시킨다면,


task1, task2는 onPreExecute()가 순서대로 호출 될 것이다. 하지만 doInBackgound를 포함한 나머지 메서드는

task1 먼저 모두 끝난 뒤에 task2가 순차적으로 호출 될 것이다.


(궁금하다면 한번 테스트 해보시는게 좋다. 백문이 불어일테스트)


물론 AsyncTask에 정의되어있는 ThreadExecutor 는 하나만 있는 것은 아니다.


1
    public static final Executor THREAD_POOL_EXECUTOR;
cs



AsyncTask 205라인을 확인하면 위와같이 다른 Executor가 정의되있다.

(이것 또한 SDK 버전에 따라 라인이 다를 수 있다.)


THREAD_POOL_EXECUTOR 는 아래와 같이 정의 되어 있다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
    // We want at least 2 threads and at most 4 threads in the core pool,
    // preferring to have 1 less than the CPU count to avoid saturating
    // the CPU with background work
    private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 14));
    private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
    private static final int KEEP_ALIVE_SECONDS = 30;
 
 
    /**
     * An {@link Executor} that can be used to execute tasks in parallel.
     */
    public static final Executor THREAD_POOL_EXECUTOR;
 
    static {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS,
                sPoolWorkQueue, sThreadFactory);
        threadPoolExecutor.allowCoreThreadTimeOut(true);
        THREAD_POOL_EXECUTOR = threadPoolExecutor;
    }
cs


한번에 구동 될 수 있는 AsyncTask의 개수, 생존 시간 등등이 정의 되어있다.

만약 간단하게 동시에 여러개의 AsyncTask를 동작시키고 싶다면 아래와같이 실행하면된다.


1
2
3
4
        DownloadFilesTask task1 = new DownloadFilesTask();
        task1.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "http://....");
        DownloadFilesTask task2 = new DownloadFilesTask();
        task2.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "http://....");
cs


처음과 달리 2개의 AsyncTask가 불규칙 적으로 동시에 실행 될 것이다.

(정의된 ThreadPool의 개수가 초과되지 않는다면)


이 외에도 여러개의 ThreadPoolExecutor가 있다.

java.util.concurrent 패키지의 Executors를 확인 할 수 있다.


AsyncTask Executors


위 안드로이드 레퍼런스를 참고하여 개발시 AsyncTask Thread동작에 맞는 ThreadPool & 스케쥴링을 선택 하면 된다.