摘要:Fork/Join框架位于J.U.C(java.util.concurrent)中,是Java7中提供的用于执行并行任务的框架,其可以将大任务分割成若干个小任务,最终汇总每个小任务的结果后得到最终结果。

本文分享自华为云社区《如何使用Java7提供的Fork/Join框架实现高并发程序?》,作者:冰 河。

Fork/Join框架位于J.U.C(java.util.concurrent)中,是Java7中提供的用于执行并行任务的框架,其可以将大任务分割成若干个小任务,最终汇总每个小任务的结果后得到最终结果。基本思想和Hadoop的MapReduce思想类似。

主要采用的是工作窃取算法(某个线程从其他队列里窃取任务来执行),并行分治计算中的一种Work-stealing策略

为什么需要使用工作窃取算法呢?

假如我们需要做一个比较大的任务,我们可以把这个任务分割为若干互不依赖的子任务,为了减少线程间的竞争,于是把这些子任务分别放到不同的队列里,并为每个队列创建一个单独的线程来执行队列里的任务,线程和队列一一对应,比如A线程负责处理A队列里的任务。但是有的线程会先把自己队列里的任务干完,而其他线程对应的队列里还有任务等待处理。干完活的线程与其等着,不如去帮其他线程干活,于是它就去其他线程的队列里窃取一个任务来执行。而在这时它们会访问同一个队列,所以为了减少窃取任务线程和被窃取任务线程之间的竞争,通常会使用双端队列,被窃取任务线程永远从双端队列的头部拿任务执行,而窃取任务的线程永远从双端队列的尾部拿任务执行。

工作窃取算法的优点

充分利用线程进行并行计算,并减少了线程间的竞争

工作窃取算法的缺点

在某些情况下还是存在竞争,比如双端队列里只有一个任务时。并且该算法会消耗更多的系统资源,比如创建多个线程和多个双端队列。

Fork/Join框架局限性

对于Fork/Join框架而言,当一个任务正在等待它使用Join操作创建的子任务结束时,执行这个任务的工作线程查找其他未被执行的任务,并开始执行这些未被执行的任务,通过这种方式,线程充分利用它们的运行时间来提高应用程序的性能。为了实现这个目标,Fork/Join框架执行的任务有一些局限性,如下所示。

  • 任务只能使用Fork和Join操作来进行同步机制,如果使用了其他同步机制,则在同步操作时,工作线程就不能执行其他任务了。比如,在Fork/Join框架中,使任务进行了睡眠,那么,在睡眠期间内,正在执行这个任务的工作线程将不会执行其他任务了。
  • 在Fork/Join框架中,所拆分的任务不应该去执行IO操作,比如:读写数据文件
  • 任务不能抛出检查异常,必须通过必要的代码来出来这些异常

Fork/Join框架的核心类

Fork/Join框架的核心是两个类:ForkJoinPool和ForkJoinTask。ForkJoinPool负责实现工作窃取算法、管理工作线程、提供关于任务的状态以及执行信息。ForkJoinTask主要提供在任务中执行Fork和Join操作的机制。

示例代码

示例代码如下:

package io.binghe.concurrency.example.aqs;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future;
import java.util.concurrent.RecursiveTask;
@Slf4j
public class ForkJoinTaskExample extends RecursiveTask<Integer> {
public static final int threshold = 2;
private int start;
private int end;
public ForkJoinTaskExample(int start, int end) {
this.start = start;
this.end = end;
}
@Override
protected Integer compute() {
int sum = 0;
//如果任务足够小就计算任务
boolean canCompute = (end - start) <= threshold;
if (canCompute) {
for (int i = start; i <= end; i++) {
sum += i;
}
} else {
// 如果任务大于阈值,就分裂成两个子任务计算
int middle = (start + end) / 2;
ForkJoinTaskExample leftTask = new ForkJoinTaskExample(start, middle);
ForkJoinTaskExample rightTask = new ForkJoinTaskExample(middle + 1, end);
// 执行子任务
leftTask.fork();
rightTask.fork();
// 等待任务执行结束合并其结果
int leftResult = leftTask.join();
int rightResult = rightTask.join();
// 合并子任务
sum = leftResult + rightResult;
}
return sum;
}
public static void main(String[] args) {
ForkJoinPool forkjoinPool = new ForkJoinPool();
//生成一个计算任务,计算1+2+3+4
ForkJoinTaskExample task = new ForkJoinTaskExample(1, 100);
//执行一个任务
Future<Integer> result = forkjoinPool.submit(task);
try {
log.info("result:{}", result.get());
} catch (Exception e) {
log.error("exception", e);
}
}
}

点击关注,第一时间了解华为云新鲜技术~

Java7提供的Fork/Join框架实现高并发程序,你会使用吗?的更多相关文章

  1. 使用Java7提供的Fork/Join框架

    http://blog.csdn.net/a352193394/article/details/39872923 使用Java7提供的Fork/Join框架 2014-10-07 23:55 4818 ...

  2. Java 7 Fork/Join 框架

    在 Java7引入的诸多新特性中,Fork/Join 框架无疑是重要的一项.JSR166旨在标准化一个实质上可扩展的框架,以将并行计算的通用工具类组织成一个类似java.util中Collection ...

  3. Java开发笔记(一百零六)Fork+Join框架实现分而治之

    前面依次介绍了普通线程池和定时器线程池的用法,这两种线程池有个共同点,就是线程池的内部线程之间并无什么关联,然而某些情况下的各线程间存在着前因后果关系.譬如人口普查工作,大家都知道我国总人口为14亿左 ...

  4. 使用Java7提供Fork/Join框架

    在Java7在.JDK它提供了多线程开发提供了一个非常强大的框架.这是Fork/Join框架.这是原来的Executors更多 进一步,在原来的基础上添加了并行分治计算中的一种Work-stealin ...

  5. Java7任务并行执行神器:Fork&Join框架

    Fork/Join是什么? Fork/Join框架是Java7提供的并行执行任务框架,思想是将大任务分解成小任务,然后小任务又可以继续分解,然后每个小任务分别计算出结果再合并起来,最后将汇总的结果作为 ...

  6. Java7任务并行执行神器:Fork&Join框架

    原 Java7任务并行执行神器:Fork&Join框架 2018年01月12日 17:25:03 Java技术栈 阅读数:426 标签: JAVAFORKJOIN 更多 个人分类: Java ...

  7. Fork/Join 框架框架使用

    1.介绍 Fork/Join 框架是 Java7 提供了的一个用于并行执行任务的框架, 是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架.在多核计算机中正确使用可以很好的 ...

  8. 013-多线程-基础-Fork/Join框架、parallelStream讲解

    一.概述 Fork/Join框架是Java7提供了的一个用于并行执行任务的框架, 是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架. 它同ThreadPoolExecut ...

  9. 一文带你了解J.U.C的FutureTask、Fork/Join框架和BlockingQueue

    摘要: J.U.C是Java并发编程中非常重要的工具包,今天,我们就来着重讲讲J.U.C里面的FutureTask.Fork/Join框架和BlockingQueue. 本文分享自华为云社区<[ ...

  10. 聊聊并发(八)——Fork/Join框架介绍

      作者 方腾飞 发布于 2013年12月23日 | 被首富的“一个亿”刷屏?不如定个小目标,先把握住QCon上海的优惠吧!2 讨论 分享到:微博微信FacebookTwitter有道云笔记邮件分享 ...

随机推荐

  1. overflow 隐藏滚动条样式

    在使用overflow,属性值为auto或者scroll时,很多时候会有多余的滚动条在旁边,这时就非常影响观瞻,所以我们有时需要将滚动条隐藏掉. 今天就说两种我用到的隐藏滚动条的方法,如果有其他解决方 ...

  2. A-卷积网络压缩方法总结

    卷积网络的压缩方法 一,低秩近似 二,剪枝与稀疏约束 三,参数量化 四,二值化网络 五,知识蒸馏 六,浅层网络 我们知道,在一定程度上,网络越深,参数越多,模型越复杂,其最终效果越好.神经网络的压缩算 ...

  3. 创建Vue工程常用的命令

    创建一个vue项目的步骤 1.创建一个名称为myapp的工程 vue init webpack myapp 2.进入工程目录 cd myapp 3.安装 vue-router npm install ...

  4. jenkins集成基于maven的javaweb项目,部署到docker容器中

    使用开源工具:Jenkins,码云gitee,docker,docker页面管理工具PortainerUI,github 各种工具的安装就不必介绍了,首先打开Jenkins,刚安装完Jenkins,可 ...

  5. ElasticSearch之Windows中环境安装

    ElasticSearch 说明 本章,我们主要以在 Windows 中对ElasticSearch 安装进行介绍! 1. 下载 ElasticSearch 这里我们下载的版本为7.17.4为例进行介 ...

  6. Trino Worker 规避 OOM 思路

    背景 Trino 集群如果不做任何配置优化,按照默认配置上线,Master 和 Worker 节点都很容易发生 OOM.本文从 Trino 内存设计出发, 分析 Trino 内存管理机制,到限制与优化 ...

  7. JavaScript进阶(Learning Records)

    背景:对JavaScript的深入学习 参考:<JavaScript高级程序设计><冴羽 JavaScript 深入> 从原型到原型链 prototype prototype是 ...

  8.  iOS App 上架App Store及提交审核详细教程

    上架App Store审核分7步进行: 1.安装iOS上架辅助软件Appuploader 2.申请iOS发布证书(p12) 3.申请iOS发布描述文件(mobileprovision) 4.打包ipa ...

  9. Python基础之面向对象:1、面向对象及编程思想

    一.人狗大战 1.需求 用代码模拟人.狗打架的小游戏 人和狗种类不同,因此双方的属性各不相同 推导一: 人和狗各有不同属性 使用字典方式储存属性较为方便,并可储存多种属性 # 1.在字典内储存'人'属 ...

  10. 将vue+nodejs项目部署到服务器上(完整版)

    1.后端使用express生成器 1.1.后台node项目部署 在node项目里安装cors依赖(跨域)npm install cors --save,在app.js文件中使用var cors = r ...