Thread, Callable, Executor(framework) 쓰레드 다루기
Thread, Callable, Executor(framework) 쓰레드 다루기
최근 coroutine , rx 로 인해 쓰레드 체 관한 처리가 조금 쉬워지긴했다.
그래도 옛날 소스들을 보면 java thread, Executor 또는 AsyncTask를 이용해서 만들어진게 많다.
이중 주로 외부랑 httpd 통신할때 쓰면 Executor 에 대해 알아보자.
그전에 어차피 나올용어로서 Callable 과 Runnable을 알아보자
static class MyCallable implements Callable<String> {
@Override
public String call() throws Exception {
return "hehe";
}
}
/* 사용
ExecutorService mPool = Executors.newFixedThreadPool(5);
mPool.execute(new MyRunnable());
*/
static class MyRunnable implements Runnable {
@Override
public void run(){
}
}
/* 사용
Future<String> mFuture = mPool.submit(new MyCallable());
try {
// 미래(future)에서 데이터가 오기까지 여기는 런타임 블럭처리된다.
Log.e("from Future", mFuture.get());
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
*/
- Callable : 보면 알겠지만 리턴값을 지정할수 있고 call() 로 실행한다. 또 에러처리를 할수 있어서 쓰레드실행시에 문제가 생겼을때 사용자가 적절한 처리를 할수있다.
- Runnale : run으로 실행한다.
Executor Framework는 자바 1.5 부터 제공해주는 것으로 기존의 단순 Thread 를 프레임워크화 해서 좀덛 쓰레드를 유연하게 사용하도록 해 준다.
대표 기능으로 thread pool, 생명주기 관리, Task 관리, 병렬처리(?), 비동기(Future)처리지원 등이다.
아래는 Future를 사용한 비동기 처리 예제이다.
static class MyCallable implements Callable<String> {
CountDownLatch howMuchCounting;
String s = "";
@Override
public String call() throws Exception {
howMuchCounting.countDown();
return "http://ohmy.god?" + s;
}
public void setS(String argS) {
s = argS;
}
public void setCountDowner(CountDownLatch argHowMuchCounting) {
howMuchCounting = argHowMuchCounting;
}
}
private void runExe() {
CountDownLatch howMuchCounting = new CountDownLatch(3);
ExecutorService mPool = Executors.newFixedThreadPool(5);
List<String> yourInputDatas = Arrays.asList("page=1", "page=2", "page=3");
List<Future<String>> futures = new ArrayList<Future<String>>();
for (final String dataItem : yourInputDatas) {
MyCallable myCallable = new MyCallable();
myCallable.setS(dataItem);
myCallable.setCountDowner(howMuchCounting);
futures.add(mPool.submit(myCallable));
}
// 바로 아래의 await로 쓰레드가 모두 실행될때까지 기다린다.
try {
howMuchCounting.await();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
// 모두 끝났으면 셧다운
mPool.shutdown();
List<String> results = new ArrayList<String>();
for (Future<String> future : futures) {
// future에 있는 데이터는 그래도 사용 하기 번거로우니까 따로 담는다.
try {
results.add(future.get());
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (String s : results) {
Log.i("fure", s);
}
}
/*
fure: http://ohmy.god?page=1
fure: http://ohmy.god?page=2
fure: http://ohmy.god?page=3
*/
CountDownLatch 클래스는 동시성관련 유틸 클래스로서 초기에 몇개의 쓰레드가 동시에 이루질수 있는지 지정하고, 쓰레드의 각 처리가 끝나는 순간 하나씩 countDown하여 0 이 될때까지 await 함수를 통해 비동기작업이 끝나기를 기다리게 해준다.
이를 이용하여 모든 쓰레드를 강제로 닫는 shutdown 을 사용해도 문제가 없도록 구현할수 있게 해준다.
0 comments:
댓글 쓰기