ForkJoinPool 사용

2362 단어 다중 스레드
1. 소개
ForkJoinPool은 주로 분치 알고리즘을 이용하여 하나의 큰 임무를 하나의 작은 임무로 나누고 작은 임무의 결과를 종합하여 큰 임무의 결과를 얻는다. 아래의 demo는 1에서 1000000의 총계를 계산하는 것이다. 0->4,5->9,10->14를 계산한다.등등, 각 조의 값을 누적하여 총계를 얻는다.
2. ForkJoinPool은 demo를 사용합니다.
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
import java.util.stream.LongStream;

@Slf4j
public class ForkJoinPoolTest {

    public static void main(String[] args) {
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        //                    ,ForkJoinPool            cpu  
        int size = 1000000;

        long forkJoinStartTime = System.currentTimeMillis();
        long[] numbers = LongStream.rangeClosed(1, size).toArray();
        Long result = forkJoinPool.invoke(new MyRecursiveTask(numbers, 0, size-1)); //     ,   
        long forkJoinEndTime = System.currentTimeMillis();
        System.out.println("running time:" + (forkJoinEndTime - forkJoinStartTime));
        System.out.println("result:"+result);
        forkJoinPool.shutdown();//  forkJoinPool 
    }

    private static class MyRecursiveTask extends RecursiveTask { //RecursiveTask     ,RecursiveAction     

        private long[] numbers;
        private int start;
        private int end;

        public MyRecursiveTask(long[] numbers, int start, int end) {
            this.numbers = numbers;
            this.start = start;
            this.end = end;
        }

        @Override
        protected Long compute() {
            if (start - end <= 5) {//         5      
                Long total = 0L;
                for (int i = start; i <= end; i++) {
                    total += numbers[i];
                }
                return total;
            } else {
                int middle = (start + end) / 2;
                MyRecursiveTask left = new MyRecursiveTask(numbers, start, middle); //         ,             
                MyRecursiveTask right = new MyRecursiveTask(numbers, middle + 1, end);
                MyRecursiveTask.invokeAll(left,right);
                return left.join() + right.join(); //        
            }
        }
    }
}

3. ForkJoinPool 실전
업무 중에 자주 공휴일이나 행사일이 되면 모든 사용자의 번호로 문자를 보내야 한다. 방대한 사용자 수에 직면하여 문자를 순서대로 실행하면 시간이 많이 걸릴 수 있다. Executor 서비스 스레드 풀을 사용해서 동시에 할 수도 있고 ForkJoinPool을 사용해서 할 수도 있다.

좋은 웹페이지 즐겨찾기