보통 async task 를 inner class 를 바로 인스턴스 하는 형태로 쓰다가 메모리 닉 문제가 있다보니 별도의 static 클래스로 구성하여
사용했는데 쓰던 버릇이 있어서 이게 좀 귀찮았다.
그러던 차에 Executors 에 대해 알게 되었고 이를 사용하는데 이 녀석이 어떻게 동작하는지에 대해서
알아야할 필요성이 있어서 잠시 테스트를 시도 했다.
Executors.newSingleThreadExecutor 을 이용시 일반적인 AsyncTask 의 execute 처럼
동작하는지 아니면 executeOnExecutor 처럼 동작하는지를 확인할 테스트 코드로 아래와 같이 구성하였고
static Integer mCount = 0;
static class TestAsyncTask extends AsyncTask<Void, Boolean, Boolean> {
@Override
protected Boolean doInBackground(Void... voids) {
try {
Thread.sleep(1000);
synchronized (mCount) {
if (mLog.isDebugEnabled()) {
mLog.debug("THREAD : " + mCount++);
}
}
} catch (Exception e) {
mLog.error("ERROR: " + e.getMessage());
}
return null;
}
}
static class TestAsyncTask2 extends AsyncTask<Void, Boolean, Boolean> {
@Override
protected Boolean doInBackground(Void... voids) {
try {
Thread.sleep(1000);
synchronized (mCount) {
if (mLog.isDebugEnabled()) {
mLog.debug("THREAD2 : " + mCount++);
}
}
} catch (Exception e) {
mLog.error("ERROR: " + e.getMessage());
}
return null;
}
}
이렇게 AsyncTask 를 생성하고 click 이벤트를 통해 테스트를 진행 했다.
btn.setOnClickListener(v -> {
new TestAsyncTask().execute();
new TestAsyncTask().execute();
new TestAsyncTask2().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
new TestAsyncTask2().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
Executors.newSingleThreadExecutor().execute(() -> {
try {
Thread.sleep(1000);
synchronized (mCount) {
if (mLog.isDebugEnabled()) {
mLog.debug("(EXECUTOR 1) : " + mCount++);
}
}
} catch (Exception e) {
}
});
Executors.newSingleThreadExecutor().execute(() -> {
try {
Thread.sleep(500);
synchronized (mCount) {
if (mLog.isDebugEnabled()) {
mLog.debug("EXECUTOR 2 : " + mCount++);
}
}
} catch (Exception e) {
}
});
});
결과로 출력된 로그는 아래와 같다.
D/[HSP]: MainActivity.lambda$null$2$MainActivity(MainActivity.java:126) EXECUTOR 2 : 0
D/[HSP]: MainActivity.lambda$null$1$MainActivity(MainActivity.java:112) (EXECUTOR 1) : 1
D/[HSP]: MainActivity$TestAsyncTask2.doInBackground(MainActivity.java:168) THREAD2 : 2
D/[HSP]: MainActivity$TestAsyncTask2.doInBackground(MainActivity.java:168) THREAD2 : 3
D/[HSP]: MainActivity$TestAsyncTask.doInBackground(MainActivity.java:150) THREAD : 4
D/[HSP]: MainActivity$TestAsyncTask.doInBackground(MainActivity.java:150) THREAD : 5
executeOnExecutor 처럼 동작하는 것 그리고 더 찾아봐야겠지만 AsyncTask 보다 우선권이 있다는것
SERIAL 하게 동작을 원한다면 AsyncTask 를 아니면 Executors.newSingleThreadExecutors 를
사용해도록 결정..
일단 Rx 를 위해서도 submit() 을 이용해 Future 로 Observable 를 생성할 수 있어서 연관성이 있다.
사용했는데 쓰던 버릇이 있어서 이게 좀 귀찮았다.
그러던 차에 Executors 에 대해 알게 되었고 이를 사용하는데 이 녀석이 어떻게 동작하는지에 대해서
알아야할 필요성이 있어서 잠시 테스트를 시도 했다.
Executors.newSingleThreadExecutor 을 이용시 일반적인 AsyncTask 의 execute 처럼
동작하는지 아니면 executeOnExecutor 처럼 동작하는지를 확인할 테스트 코드로 아래와 같이 구성하였고
static Integer mCount = 0;
static class TestAsyncTask extends AsyncTask<Void, Boolean, Boolean> {
@Override
protected Boolean doInBackground(Void... voids) {
try {
Thread.sleep(1000);
synchronized (mCount) {
if (mLog.isDebugEnabled()) {
mLog.debug("THREAD : " + mCount++);
}
}
} catch (Exception e) {
mLog.error("ERROR: " + e.getMessage());
}
return null;
}
}
static class TestAsyncTask2 extends AsyncTask<Void, Boolean, Boolean> {
@Override
protected Boolean doInBackground(Void... voids) {
try {
Thread.sleep(1000);
synchronized (mCount) {
if (mLog.isDebugEnabled()) {
mLog.debug("THREAD2 : " + mCount++);
}
}
} catch (Exception e) {
mLog.error("ERROR: " + e.getMessage());
}
return null;
}
}
이렇게 AsyncTask 를 생성하고 click 이벤트를 통해 테스트를 진행 했다.
btn.setOnClickListener(v -> {
new TestAsyncTask().execute();
new TestAsyncTask().execute();
new TestAsyncTask2().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
new TestAsyncTask2().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
Executors.newSingleThreadExecutor().execute(() -> {
try {
Thread.sleep(1000);
synchronized (mCount) {
if (mLog.isDebugEnabled()) {
mLog.debug("(EXECUTOR 1) : " + mCount++);
}
}
} catch (Exception e) {
}
});
Executors.newSingleThreadExecutor().execute(() -> {
try {
Thread.sleep(500);
synchronized (mCount) {
if (mLog.isDebugEnabled()) {
mLog.debug("EXECUTOR 2 : " + mCount++);
}
}
} catch (Exception e) {
}
});
});
결과로 출력된 로그는 아래와 같다.
D/[HSP]: MainActivity.lambda$null$2$MainActivity(MainActivity.java:126) EXECUTOR 2 : 0
D/[HSP]: MainActivity.lambda$null$1$MainActivity(MainActivity.java:112) (EXECUTOR 1) : 1
D/[HSP]: MainActivity$TestAsyncTask2.doInBackground(MainActivity.java:168) THREAD2 : 2
D/[HSP]: MainActivity$TestAsyncTask2.doInBackground(MainActivity.java:168) THREAD2 : 3
D/[HSP]: MainActivity$TestAsyncTask.doInBackground(MainActivity.java:150) THREAD : 4
D/[HSP]: MainActivity$TestAsyncTask.doInBackground(MainActivity.java:150) THREAD : 5
executeOnExecutor 처럼 동작하는 것 그리고 더 찾아봐야겠지만 AsyncTask 보다 우선권이 있다는것
SERIAL 하게 동작을 원한다면 AsyncTask 를 아니면 Executors.newSingleThreadExecutors 를
사용해도록 결정..
일단 Rx 를 위해서도 submit() 을 이용해 Future 로 Observable 를 생성할 수 있어서 연관성이 있다.
'Android' 카테고리의 다른 글
calling koltin from java (0) | 2018.08.31 |
---|---|
sublime text 3 hom / end key macOs 에서 설정하기 (0) | 2018.08.31 |
sublime text 3 hom / end key macOs 에서 설정하기 (0) | 2018.08.10 |
Observable.fromFuture (0) | 2018.08.08 |
Executor.execute ()와 ExecutorService.submit () 메서드 비교 (0) | 2018.08.08 |