invoke
메소드를 통해서 task 또는 action 을 실행을 해준다.awaitTermination
메소드를 선언을 해주나다. 기본적으로 선언된 시간이 지나게 경과 하면 false 를 아니면 true 를 반환 한다.정리:
awaitTermination ->
ForkJoinPool 클래스의 awaitTermination() 메서드는 종료 요청 후 종료 또는 매개 변수로 지정된 시간 초과를 기다리는 데 사용됩니다.
프로그램이 종료될 때까지 시간 초과가 경과한다.
커먼 풀로 호출될 때, 그것은 awaitQuiescence() 메소드 역할을 한다.
실행기가 종료되면 true를 반환하고 시간 초과로 지정된 시간이 경과하면 false를 반환합니다.
스레드의 병렬 처리를 위하여 RecursiveTask 와 RecursiveAction 을 사용을 한다.
두가지 모드 병렬 처리 작업이 라는 공통점을 가지고 있지만 차이점이 존재를 한다.
RecursiveAction 의 경우 단순하게 병렬 처리를 한다. return 값을 사용을 하지 않는다.
그에 비해 RecursiveTask 의 경우 상속을 받을때 제네릭에 리턴 값을 선언을 해준다. 리턴 값을 가지고
값을 합산 혹은 값을 반환하는 작업을 처리를 할 수 있다.
선언 부에서 invoke
메소드 를 통해서 작업을 넣어주면 compute 메소드를 호출을 한다.
이때 우리는 작업에 대한 분할을 해주어야 되기때문에 분할 조건을 넣어준다.
RecursiveTask 으로 설명을 하자면
기본적인 메소드 흐름의 경우
리스트를 분할 처리 하기 위해서 코드를 보면 100 개 초과일시 분할을 시키고 100 이하 일시 count 치는 로직을 구현을 해주었다.
하지만 리스트 분할을 처리를 해주어야 하기 때문에 리스트 배열에 작업을 할당을 시켜주고 그후에 fork 로 다시 작업을 진행을 해준다.
fork 가 끝나면 join 으로 작업을 다시 모야준다.
분할의 경우 하나의 테스크는 2개로 만 쪼개지게 하였다. 1 -> 2 -> 4 -> 8 계속해서 2^n 만큼 조건에 부합하게 분할을 해준다.
그렇기 때문에 하나의 테스크에 모든것을 분할 하는 것이 아니라 균등한 분할을 할 수 있다. 여기서 키포인트는 하나의 테스크의 큐가 없다면 다른 테스크의 큐에서
작업을 자기고 간다는 점이다.
RecursiveAction 의 경우 사실 RecursiveTask 와의 차이점은 위에서 언급했듯이 return 값 유무이다.
fork 만 선언을 해주고 join 은 하지 않는다 그만큼 join 을 안하기 때문에 task 의 비해 효율성은 높다고 할 수 있다.