我眼中的并发编程——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 条评论
登录 后参与评论

相关文章

来自专栏Ceph对象存储方案

Luminous版本PG 分布调优

Luminous版本开始新增的balancer模块在PG分布优化方面效果非常明显,操作也非常简便,强烈推荐各位在集群上线之前进行这一操作,能够极大的提升整个集群...

3105
来自专栏跟着阿笨一起玩NET

c#实现打印功能

2702
来自专栏大内老A

The .NET of Tomorrow

Ed Charbeneau(http://developer.telerik.com/featured/the-net-of-tomorrow/) Exciti...

31610
来自专栏张善友的专栏

Miguel de Icaza 细说 Mix 07大会上的Silverlight和DLR

Mono之父Miguel de Icaza 详细报道微软Mix 07大会上的Silverlight和DLR ,上面还谈到了Mono and Silverligh...

2707
来自专栏hbbliyong

WPF Trigger for IsSelected in a DataTemplate for ListBox items

<DataTemplate DataType="{x:Type vm:HeaderSlugViewModel}"> <vw:HeaderSlug...

4064
来自专栏我和未来有约会

Silverlight第三方控件专题

这里我收集整理了目前网上silverlight第三方控件的专题,若果有所遗漏请告知我一下。 名称 简介 截图 telerik 商 RadC...

4015
来自专栏一个会写诗的程序员的博客

Spring Reactor 项目核心库Reactor Core

Non-Blocking Reactive Streams Foundation for the JVM both implementing a Reactiv...

2152
来自专栏魂祭心

原 canvas绘制clock

4064
来自专栏菩提树下的杨过

Flash/Flex学习笔记(23):运动学原理

先写一个公用的小球类Ball: package{ import flash.display.Sprite; //小球 类 public class B...

25310
来自专栏芋道源码1024

熔断器 Hystrix 源码解析 —— 断路器 HystrixCircuitBreaker

本文主要基于 Hystrix 1.5.X 版本 1. 概述 2. HystrixCircuitBreaker 3. HystrixCircuitBreaker....

5287

扫码关注云+社区