线程池(三):ForkJoinPool


prtyaa
prtyaa 2023-12-28 16:41:14 51004 赞同 0 反对 0
分类: 资源
本质是一个线程池,默认的线程数量是cpu的核数
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;

public class Test {

    static List<String> urls = new ArrayList<String>() {
        {
            add("http://www.baidu.com");
            add("http://www.sina.com");
            add("http://www.baidu.com");
            add("http://www.sina.com");
            add("http://www.baidu.com");
            add("http://www.sina.com");
            add("http://www.baidu.com");
            add("http://www.sina.com");
            add("http://www.baidu.com");
            add("http://www.sina.com");
            add("http://www.baidu.com");
            add("http://www.sina.com");
            add("http://www.baidu.com");
            add("http://www.sina.com");
            add("http://www.baidu.com");
            add("http://www.sina.com");
            add("http://www.baidu.com");
            add("http://www.sina.com");
            add("http://www.baidu.com");
            add("http://www.sina.com");
            add("http://www.baidu.com");
            add("http://www.sina.com");
        }
    };
    // 本质是一个线程池,默认的线程数量:CPU的核数
    static ForkJoinPool forkJoinPool = new ForkJoinPool(3,
            ForkJoinPool.defaultForkJoinWorkerThreadFactory,
            null,
            true);
    public static String doRequest(String url,int index) {
        return index+" test " + url + "\n";
    }

    static class Job extends RecursiveTask<String> {
        List<String> urls;
        int start;
        int end;

        public Job(List<String> urls, int start, int end) {
            this.urls = urls;
            this.start = start;
            this.end = end;
        }

        @Override
        protected String compute() {
            int count = end - start;
            if (count <= 10) {
                String result = "";
                for (int i = start; i < end; i++) {
                    String s = doRequest(urls.get(i),i);
                    result = result + s;
                }
                return result;
            } else {
                int mid = (start + end) / 2;
                Job job1 = new Job(urls, start, mid);
                job1.fork();
                Job job2 = new Job(urls, mid, end);
                job2.fork();

                //固定写法
                String results = "";
                results += job1.join();
                results += job2.join();
                return results;
            }
        }
    }
    public static void main(String[] args) throws ExecutionException, InterruptedException {


        Job job = new Job(urls, 0, urls.size());
        ForkJoinTask<String> forkJoinTask = forkJoinPool.submit(job);
        String s = forkJoinTask.get();
        System.out.println(s);
    }
}

采用的就是分而治之的思想。特点是:工作窃取,当一个线程的任务执行完了之后,如果其他线程还有没执行完毕的任务,会去窃取过来执行。维护的是一个双端队列。窃取的时候从队列的底部取任务


在看一个求和的例子:从0加到10亿

ForkJoin的方式

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;

public class NumberSum extends RecursiveTask<Long> {
    private Long start;
    private Long end;

    private Long temp = 10000L;

    public NumberSum(Long start, Long end) {
        this.start = start;
        this.end = end;
    }

    //计算方法
    @Override
    protected Long compute() {
        if ((end - start) < temp) {
            Long sum = 0L;
            for (Long i = start; i <= end; i++) {
                sum += i;
            }
            return sum;
        } else {
            Long result = 0L;
            Long mid = (start + end) / 2;
            NumberSum n1 = new NumberSum(start, mid);
            n1.fork();
            NumberSum n2 = new NumberSum(mid + 1, end);
            n2.fork();
            result += n1.join();
            result += n2.join();
            return result;
        }
    }

    static ForkJoinPool forkJoinPool = new ForkJoinPool(3,
            ForkJoinPool.defaultForkJoinWorkerThreadFactory,
            null,
            true);

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        NumberSum numberSum = new NumberSum(0L, 1_0000_0000L);
        ForkJoinTask<Long> future = forkJoinPool.submit(numberSum);
        System.out.println(future.get());
    }
}

如果您发现该资源为电子书等存在侵权的资源或对该资源描述不正确等,可点击“私信”按钮向作者进行反馈;如作者无回复可进行平台仲裁,我们会在第一时间进行处理!

评价 0 条
prtyaaL2
粉丝 1 资源 1949 + 关注 私信
最近热门资源
银河麒麟桌面操作系统备份用户数据  124
统信桌面专业版【全盘安装UOS系统】介绍  119
银河麒麟桌面操作系统安装佳能打印机驱动方法  110
银河麒麟桌面操作系统 V10-SP1用户密码修改  104
最近下载排行榜
银河麒麟桌面操作系统备份用户数据 0
统信桌面专业版【全盘安装UOS系统】介绍 0
银河麒麟桌面操作系统安装佳能打印机驱动方法 0
银河麒麟桌面操作系统 V10-SP1用户密码修改 0
作者收入月榜
1

prtyaa 收益393.62元

2

zlj141319 收益218元

3

1843880570 收益214.2元

4

IT-feng 收益209.03元

5

风晓 收益208.24元

6

777 收益172.71元

7

Fhawking 收益106.6元

8

信创来了 收益105.84元

9

克里斯蒂亚诺诺 收益91.08元

10

技术-小陈 收益79.5元

请使用微信扫码

加入交流群

请使用微信扫一扫!