我眼中的并发编程——Fork/Join模型

简介

Fork/Join模型是ExecutorService的接口实现,可以帮助你利用多个处理器。它被设计用可以递归地分解成更小的任务,目的是所有可用的处理能力来提高应用程序性能,与分而治之思路类似。

与任何一个ExecutorService实现一样,Fork/Join模型将任务分配到线程池中的工作线程中。但Fork/Join框架与其他的区别是采用了工作窃取算法,工作线程任务完成后可能会从仍然忙碌的其他线程窃取任务。

Fork/Join模型的核心是ForkJoinPool,该类的扩展AbstractExecutorServiceForkJoinPool实现核心工作窃取算法,可以执行ForkJoinTask任务。

基本使用

使用Fork/Join模型第一步应该编写核心任务代码。大题逻辑如下:

if(我的任务足够小){
     直接工作
}else{
     任务划分成两份,
      执行并等待结果。
}

把这段代码封装到一个ForkJoinTask的子类中。通常做法是继承 RecursiveTask或 RecursiveAction

RecursiveTask:有返回值。
RecursiveAction:无返回值。

代码样例

package com.itunic.concurrent;

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

public class CountTask extends RecursiveTask<Long> {

 private static final long serialVersionUID = 1L;
 private long start;
 private long end;
 // 区分任务颗粒度
 private static final int THRESHOLD = 2;

 public CountTask(long start, long end) {
 this.start = start;
 this.end = end;
    }

 @Override
 protected Long compute() {
 long sum = 0;
 boolean canCompute = (end - start) <= THRESHOLD;
 // 判断任务的颗粒度是否足够小
 if (canCompute) {
 for (long i = start; i < end; i++) {
                sum += i;
            }
        } else {
 // 将数据切分
 long middle = (start + end) / 2;
            CountTask task1 = new CountTask(start, middle);
            CountTask task2 = new CountTask(middle, end);
 // 发起两个线程任务
            invokeAll(task1, task2);
 // 等待线程返回结果
 long result1 = task1.join();
 long result2 = task2.join();
            sum = result1 + result2;
        }
 return sum;
    }

 public static void main(String[] args) throws InterruptedException, ExecutionException {
        ForkJoinPool pool = new ForkJoinPool();
        ForkJoinTask<Long> future = pool.submit(new CountTask(1, 10));
        System.out.printf("统计结果为:%s",future.get());

    }

}

我的博客即将搬运同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=2head3ycz2qss

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏量化投资与机器学习

【精心解读】用pandas处理大数据——节省90%内存消耗的小贴士

本文我们讨论 pandas 的内存使用,展示怎样简单地为数据列选择合适的数据类型,就能够减少 dataframe 近 90% 的内存占用。

1.7K5
来自专栏Linyb极客之路

UML类图(下):关联、聚合、组合、依赖

关联(Assocition)关系是类与类之间最常见的一种关系,它是一种结构化的关系,表示一类对象与另一类对象之间有联系,如汽车和轮胎、师傅和徒弟、班级和学生等。...

1352
来自专栏数说工作室

移形换影 | 【SAS Says · 扩展篇】

【SAS Says·扩展篇】移形换影 | 5. call PRXCHANGE() 0. 前集回顾 1. 新的问题 2. 初识 PRXCHANGE() 3. 问题...

35011
来自专栏灯塔大数据

技术 | Python从零开始系列连载(十九)

但它的特点就是下次使用next(a)时,接着上次的断点继续运行,直到下一个yield

1013
来自专栏java一日一条

成为优秀Swift开发者的10条建议

在这里给大家分享一些帮助大家成为更优秀的Swift开发者的建议,让你的代码,写的更少,性能更优 。

1022
来自专栏take time, save time

你所能用到的BMP格式介绍(二)

一、可能你忽视的基础         在正式开始之前,我不得不从最基本的地方开始,因为这些地方大多数人会忽视的一干二净,如果不在开始进行说明,那么在后面一定会有...

2857
来自专栏ATYUN订阅号

PyTorch 4.0版本迁移指南

欢迎阅读PyTorch 0.4.0的迁移指南。在此版本中,我们引入了许多振奋人心的新功能和重要的bug修复,旨在为用户提供更好,更清晰的接口。在这个指南中,我们...

1422
来自专栏机器学习算法与Python学习

Python中的实用小技巧

关键字全网搜索最新排名 【机器学习算法】:排名第一 【机器学习】:排名第二 【Python】:排名第三 【算法】:排名第四 话说python是一个大杂会,既可以...

3305
来自专栏AI深度学习求索

算法图解(五)|散列表与字典

我们之前介绍过简单查找和二分查找,简单查找是从头开始一个个查找,二分查找是在有序列表中按分而治之的思想进行查找,虽然二分查找已经很快速了,但是在有些情况下,还是...

1061
来自专栏java达人

哈希表

哈希表是种数据结构,它可以提供快速的插入操作和查找操作。第一次接触哈希表时,它的优点多得让人难以置信。不论哈希表中有多少数据,插入和删除(有时包括侧除)只需要接...

1767

扫码关注云+社区