ForkJoinPool 과 ThreadPoolExecutor 이 대표적으로 ExecutorService를 구현한 class 이다.
Executor<-ExecutorService관계이며, Excutor가 Runnable를 실행하고, ExecutorService 에서 shutdown등으로 관리가능.
(이렇게 Factory 형태로도 많이 쓰인다)
ExecutorService pool = Executors(유틸).newFixedThreadPool (thread num) returns ExecutorSerivce.
=> newFixedThreadPool을 이용한 서버소켓 accept 예제.
pool.execute ( request ); //Executor REF
pool.shutdown() or submit() or blabla; //ExecutorService
==> 참고2 사이트: pool.submit (Callable )으로 실행되지만, 실제 Callable.call이 언제실행될지 모르므로
Executor은 Future를 리턴. future . get() : (blocking임)으로 값가져 옴.
=============ForkJoin Pool==========
ForkJoinPool에 RecursiveAction구현 객체를 invoke 하면
객체의 compute 함수가 실행되면서
compute 내에 구현된 InvokeAll(work1,work2)를 통해 멀티코어를 실행하게 된다.
<<< Factorial을 이용한 ForkJoinPool 예제 >>
public class TestPool {
public static void main(String[] args){
ForkJoinPool pool = new ForkJoinPool();
long time1 = System.currentTimeMillis();
for(int i=0; i<500000;i++){
MyWork myWork = new MyWork(25); //25factorial
pool.invoke(myWork);
}
long time2 = System.currentTimeMillis();
System.out.println("Elapse:" + (time2-time1));
}
}
class MyWork extends RecursiveAction{
int base=0;
int to=1;
long result=1;
//factorial
public MyWork(int base){
this.base = base;
}
//half factorial
public MyWork(int base, int to){
this.base = base;
this.to = to;
}
@Override
protected void compute() {
//////small value Calculate and return
if ( base-to <= 2 ){
System.out.println("END: base,to:" + base +","+to);
for ( int i=base; i >= to; i-- )
result = result*i;
return;
}
//////large value DIVIDE as 2 works.///////////////
int median = to+ (base-to)/2;
MyWork w1 = new MyWork(base, median+1);
MyWork w2 = new MyWork(median, to);
invokeAll( w1, w2); //waiting.... then why USE RecursiveTask(which resturns VALUE)
result = w1.result * w2.result;
System.out.println("FINAL RESULT:" + result);
}
}