Official account: Java Xiaokaxiu, website: Javaxks.com

Author: Xiaguangli, link: cnblogs.com/loong-hon/p/12728165.html

Start with a brief overview of the Fork/Join framework

Fork/Join framework: it is to Fork a large task into several small tasks (when they are undeassembled) when necessary, and then Join together the results of each small task operation.

Differences between Fork/Join frameworks and traditional thread pools

It uses work-stealing: When executing a new task, it can break it up into smaller tasks, add the smaller task to the thread queue, and steal one from a random thread’s queue and place it in its own queue.

The advantage of the fork/ Join framework over a generic thread pool implementation lies in the way it handles the tasks it contains. In a normal thread pool, a thread is in a wait state if the task it is executing cannot continue for some reason.

In the fork/ Join framework implementation, if a subproblem fails to run because it is waiting for another subproblem to complete. The thread handling that subproblem will actively look for other subproblems that have not yet been run to execute. This approach reduces thread wait time and improves performance.

Optimization of Fork/Join in JDK8

Fork/Join optimization in JDK8 is mainly to make Fork/Join easier to use. Fork/Join is encapsulated to simplify usage.

The underlying optimization of Fork/Join in JDK8 is not analyzed here.

The sample code

package hanwl.juc.day2;

import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;
import java.util.stream.LongStream;

import org.junit.Test;

public class TestForkJoinPool {
    
    public static void main(String[] args) {
        Instant start = Instant.now();
        
        ForkJoinPool pool = new ForkJoinPool();
        
        ForkJoinTask<Long> task = new ForkJoinSumCalculate(0L.50000000000L);
        
        Long sum = pool.invoke(task);
        
        System.out.println(sum);
        
        Instant end = Instant.now();
        
        System.out.println("Time consuming is:" + Duration.between(start, end).toMillis());/ / to the 166-1996-1059
    }
    
    @Test
    public void test1(a){
        Instant start = Instant.now();
        
        long sum = 0L;
        
        for (long i = 0L; i <= 50000000000L; i++) {
            sum += i;
        }
        
        System.out.println(sum);
        
        Instant end = Instant.now();
        
        System.out.println("Time consuming is:" + Duration.between(start, end).toMillis());/ / 35-3142-15704
    }
    
    / / java8 new features
    @Test
    public void test2(a){
        Instant start = Instant.now();
        
        Long sum = LongStream.rangeClosed(0L.50000000000L)
                             .parallel()
                             .reduce(0L, Long::sum);
        
        System.out.println(sum);
        
        Instant end = Instant.now();
        
        System.out.println("Time consuming is:" + Duration.between(start, end).toMillis());/ / 1536-8118}}class ForkJoinSumCalculate extends RecursiveTask<Long>{

    / * * * * /
    private static final long serialVersionUID = -259195479995561737L;
    
    private long start;
    private long end;
    
    private static final long THURSHOLD = 10000L;  / / the critical value
    
    public ForkJoinSumCalculate(long start, long end) {
        this.start = start;
        this.end = end;
    }

    @Override
    protected Long compute(a) {
        long length = end - start;
        
        if(length <= THURSHOLD){
            long sum = 0L;
            
            for (long i = start; i <= end; i++) {
                sum += i;
            }
            
            return sum;
        }else{
            long middle = (start + end) / 2;
            
            ForkJoinSumCalculate left = new ForkJoinSumCalculate(start, middle); 
            left.fork(); // Do the split while pressing into the thread queue
            
            ForkJoinSumCalculate right = new ForkJoinSumCalculate(middle+1, end);
            right.fork(); //
            
            returnleft.join() + right.join(); }}}Copy the code