场景:当任务很多,成千上万个,或者单个任务很大,执行起来很耗时间,这时,就可以把任务进行拆分,拆分成多个小任务去执行,然后小任务执行完毕后再把每个小任务执行的结果合并起来,这样就可以节省时间。

ForkJoinPool实现了ExecutorService接口,所以它也是一种线程池,做的工作就是,把一个任务拆分成若干个小任务执行,然后再把小任务执行的结果汇总。

下面是一个小例子:

    //初始化一个ForkJoinPool
static ForkJoinPool pool = new ForkJoinPool(3,
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
null,
true); //一个集合,模拟网站
static ArrayList<String> list = new ArrayList<>();
//集合中的数据
static void addList() {
list.add("www.baidu.com");
list.add("www.blog.csdn.net");
list.add("www.baidu.com");
list.add("www.blog.csdn.net");
list.add("www.baidu.com");
list.add("www.blog.csdn.net");
list.add("www.baidu.com");
list.add("www.blog.csdn.net");
list.add("www.baidu.com");
list.add("www.blog.csdn.net");
list.add("www.baidu.com");
list.add("www.blog.csdn.net");
list.add("www.baidu.com");
list.add("www.blog.csdn.net");
list.add("www.baidu.com");
list.add("www.blog.csdn.net");
list.add("www.baidu.com");
list.add("www.blog.csdn.net");
list.add("www.baidu.com");
list.add("www.blog.csdn.net");
list.add("www.baidu.com");
list.add("www.blog.csdn.net");
list.add("www.baidu.com");
list.add("www.blog.csdn.net");
list.add("www.baidu.com");
list.add("www.blog.csdn.net");
list.add("www.baidu.com");
list.add("www.blog.csdn.net");
list.add("www.baidu.com");
list.add("www.blog.csdn.net");
list.add("www.baidu.com");
list.add("www.blog.csdn.net");
list.add("www.baidu.com");
list.add("www.blog.csdn.net");
list.add("www.baidu.com");
list.add("www.blog.csdn.net");
list.add("www.baidu.com");
list.add("www.blog.csdn.net");
list.add("www.baidu.com");
list.add("www.blog.csdn.net");
list.add("www.baidu.com");
list.add("www.blog.csdn.net");
list.add("www.baidu.com");
list.add("www.blog.csdn.net");
list.add("www.baidu.com");
list.add("www.blog.csdn.net");
} public static void main(String[] args) throws ExecutionException, InterruptedException {
addList();
//提交任务
ForkJoinTask<String> task = pool.submit(new Work(list, 0, list.size()));
System.out.println(task.get()); } //模拟请求
public static String doRequest(String url, int index) {
return index + "--》请求测试:" + url + "\n";
} //需要继承RecursiveTask,来实现自己的拆分逻辑
static class Work extends RecursiveTask<String> {
List<String> list;
int start;
int end; public Work(List<String> list, int start, int end) {
this.list = list;
this.start = start;
this.end = end;
} @Override
protected String compute() {
int count = end - start;
String result = "";
//当任务小于10个时直接执行,否则就拆分
if (count <= 10) {
for (int i = 0; i<list.size(); i++) {
result += doRequest(list.get(i), i);
}
return result;
} else {
//获取任务数量索引的中间值
int x = (start + end) / 2;
//拆分任务
Work work1 = new Work(list, start, x);
work1.fork();
//拆分任务
Work work2 = new Work(list, x, end);
work2.fork();
//获取任务执行结果
result += work1.join();
result += work2.join();
return result;
}
}
}

执行逻辑:

第一步:

第二步:

第三步:

每一个线程有任务后,都会去拆分任务,当拆分的小任务满足执行条件后,就会去执行,然后按照层级,从拆分后最小的层级执行完任务,一层层向上回收任务结果,最后到ForkJoinTask中,然后就可以获取到每一个小任务执行的结果。

ForkJoinPool的工作原理和使用的更多相关文章

  1. 菜鸟学Struts2——Struts工作原理

    在完成Struts2的HelloWorld后,对Struts2的工作原理进行学习.Struts2框架可以按照模块来划分为Servlet Filters,Struts核心模块,拦截器和用户实现部分,其中 ...

  2. 【夯实Nginx基础】Nginx工作原理和优化、漏洞

    本文地址 原文地址 本文提纲: 1.  Nginx的模块与工作原理    2.  Nginx的进程模型    3 . NginxFastCGI运行原理        3.1 什么是 FastCGI   ...

  3. HashMap的工作原理

    HashMap的工作原理   HashMap的工作原理是近年来常见的Java面试题.几乎每个Java程序员都知道HashMap,都知道哪里要用HashMap,知道HashTable和HashMap之间 ...

  4. 【Oracle 集群】ORACLE DATABASE 11G RAC 知识图文详细教程之RAC 工作原理和相关组件(三)

    RAC 工作原理和相关组件(三) 概述:写下本文档的初衷和动力,来源于上篇的<oracle基本操作手册>.oracle基本操作手册是作者研一假期对oracle基础知识学习的汇总.然后形成体 ...

  5. ThreadLocal 工作原理、部分源码分析

    1.大概去哪里看 ThreadLocal 其根本实现方法,是在Thread里面,有一个ThreadLocal.ThreadLocalMap属性 ThreadLocal.ThreadLocalMap t ...

  6. Servlet的生命周期及工作原理

    Servlet生命周期分为三个阶段: 1,初始化阶段  调用init()方法 2,响应客户请求阶段 调用service()方法 3,终止阶段 调用destroy()方法 Servlet初始化阶段: 在 ...

  7. 代码管理工具 --- git的学习笔记二《git的工作原理》

    通过几个问题来学习代码管理工具之git 一.git是什么?为什么要用它?使用它的好处?它与svn的区别,在Mac上,比较好用的git图形界面客户端有 git 是分布式的代码管理工具,使用它是因为,它便 ...

  8. 【原】Learning Spark (Python版) 学习笔记(三)----工作原理、调优与Spark SQL

    周末的任务是更新Learning Spark系列第三篇,以为自己写不完了,但为了改正拖延症,还是得完成给自己定的任务啊 = =.这三章主要讲Spark的运行过程(本地+集群),性能调优以及Spark ...

  9. 浏览器内部工作原理--作者:Tali Garsiel

    本篇内容为转载,主要用于个人学习使用,作者:Tali Garsiel 一.介绍 浏览器可以被认为是使用最广泛的软件,本文将介绍浏览器的工作原理,我们将看到,从你在地址栏输入google.com到你看到 ...

随机推荐

  1. [C语言学习笔记三]格式化输出和输入

    使用 printf 函数来输出,使用 scanf 函数来输入 在 printf 函数中使用变量,需要使用占位符代替. int 型一般存储整数,使用 %d 代替 long long int 型一般存储长 ...

  2. R语言学习4:函数,流程控制,数据框重塑

    本系列是一个新的系列,在此系列中,我将和大家共同学习R语言.由于我对R语言的了解也甚少,所以本系列更多以一个学习者的视角来完成. 参考教材:<R语言实战>第二版(Robert I.Kaba ...

  3. 第47天打卡学习(单例模式 深入了解CAS 原子引用 各种锁的理解)

    18彻底玩转 单例模式 饿汉式 DCL懒汉模式 探究! 饿汉式  package com.kuang.single; //饿汉式单例 //单例模式重要思想是构造器私有 public class Hun ...

  4. PHP代码审计_用==与===的区别

    目录 背景介绍 如何审计 绕过案例1 绕过案例2 背景介绍 比较==与===的差别 == 是等于符号,=== 是恒等于符号,两个符号的功能都是用来比较两个变量是否相等的,只不过两个符号的比较维度不一样 ...

  5. 如何在netcore下,愉快的使用IServiceProvider

    之前一直做dotnet framework开发,依赖注入使用Autofac,Autofac的一般用法是服务启动时,将用到的接口.实现类名注入进去, 然后在服务其他地方如果使用该类时,直接在Contai ...

  6. 剑指 Offer 49. 丑数 + 小根堆 + 动态规划

    剑指 Offer 49. 丑数 Offer_49 题目详情 解法一:小根堆+哈希表/HashSet 根据丑数的定义,如果a是丑数,那么a2, a3以及a*5都是丑数 可以使用小根堆存储按照从小到大排序 ...

  7. Docker搭建HAproxy+tomcat 实现高可用

    构建业务镜像1创建tomcat-app1和tomcat-app2两个目录,代表不同的两个基于tomcat的业务.准备tomcat的配置文件[root@localhost ~]#mkdir -p /da ...

  8. Apache配置 1. 默认虚拟主机

    编辑httpd.conf搜索httpd-vhosts,去掉#号 # vi /usr/local/apache2.4/conf/httpd.conf Include conf/extra/httpd-v ...

  9. Lzzy高级语言程序设计之for循环

    public class Mq { public static void main(String[]args){ int a = 3 ; a++;// do{ System.out.println(& ...

  10. Go语言学习 学习资料汇总

    从进入实验室以来,一直听小溪师兄说Go语言,但是第一学期的课很多,一直没有时间学习,现在终于空出来时间学习,按照我的学习习惯,我一般分为三步走 学习一门语言首先要知道学会了能干什么, 然后再把网上的资 ...