多核时代,编程语言如果不支持多核编程就OUT了,Java为了迎头赶上,在Java 8 版本增加大量支持多核编程的类库,如Stream等,Java 7开始支持的ForkJoin框架也是为了更好的支持多核编程。

设计思想:化整为零再化零为整,另外还要加上一种团队精神,即能者多劳。化整为零(split up)就是把一个复杂的任务分为许多足够小的任务计算;化零为整(merge)就是把小任务的计算结果不断往上合并值到得出最终结果;团队精神:ForkJoin使用了Work-Stealing算法,即先完成任务的线程不会闲着,会主动去偷别的线程待处理任务队列中的任务来帮忙处理,直到全部任务都处理完大伙才能停下来休息。

使用ForkJoin框架经常使用到两个类RecursiveTask 和 RecursiveAction,RecursiveTask 用于定义有返回值的任务,RecursiveAction用于定义没有返回值的任务,从类名看这两个类应该跟递归有一腿?经确认,ForkJoin框架处理的任务基本都能使用递归处理,比如求斐波那契数列等,但递归算法的缺陷是:一只会只用单线程处理,二是递归次数过多时会导致堆栈溢出;ForkJoin解决了这两个问题,使用多线程并发处理,充分利用计算资源来提高效率,同时避免堆栈溢出发生。当然像求斐波那契数列这种小问题直接使用线性算法搞定可能更简单,实际应用中完全没必要使用ForkJoin框架,所以ForkJoin是核弹,是用来对付大家伙的,比如超大数组排序。

最佳应用场景:多核、多内存、可以分割计算再合并的计算密集型任务。

ForkJoinTask类的几个重要方法:

fork()方法:将任务放入队列并安排异步执行,一个任务应该只调用一次fork()函数,除非已经执行完毕并重新初始化。

tryUnfork()方法:尝试把任务从队列中拿出单独处理,但不一定成功。

join()方法:等待计算完成并返回计算结果。

isCompletedAbnormally()方法:用于判断任务计算是否发生异常。

ForkJoinPool的使用与其它ExecutorService类似。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package com.stevex.app.forkjoin;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future;
import java.util.concurrent.RecursiveTask;
public class ForkJoinTest {
    public static void main(String[] args) {
        long beginTime = System.nanoTime();     
        System.out.println("The sum from 1 to 1000 is " + sum(11000));
        System.out.println("Time consumed(nano second) By recursive algorithm : " + (System.nanoTime() - beginTime));
         
         
        beginTime = System.nanoTime();   
        System.out.println("The sum from 1 to 1000000000 is " + sum1(11000000000));
        System.out.println("Time consumed(nano second) By loop algorithm : " + (System.nanoTime() - beginTime));
         
         
        ForkJoinTest app = new ForkJoinTest();
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        CountTask task = app.new CountTask(1,1000000000);
        beginTime = System.nanoTime();
        Future<Long> result = forkJoinPool.submit(task);
        try{
            System.out.println("The sum from 1 to 1000000000 is " + result.get());        
        }
        catch(Exception e){
            e.printStackTrace();
        }
         
        System.out.println("Time consumed(nano second) By ForkJoin algorithm : " + (System.nanoTime() - beginTime));
    }
    private static long sum1(long start, long end) {
        long s = 0l;
         
        for(long i=start; i<= end; i++){
            s += i;
        }
         
        return s;
    }
    private static long sum(long start, long end){
        if(end > start){
            return end + sum(start, end-1);
        }
        else{
            return start;
        }
    }
     
    private class CountTask extends RecursiveTask<Long>{
        private static final int THRESHOLD = 10000;
        private int start;
        private int end;
         
        public CountTask(int start, int end){
            this.start = start;
            this.end = end;
        }
         
        protected Long compute(){
            //System.out.println("Thread ID: " + Thread.currentThread().getId());
             
            Long sum = 0l;
             
            if((end -start) <= THRESHOLD){
                sum = sum1(start, end);
            }
            else{
                int middle = (start + end) / 2;
                CountTask leftTask = new CountTask(start, middle);
                CountTask rightTask = new CountTask(middle + 1, end);
                leftTask.fork();
                rightTask.fork();
                 
                Long leftResult = leftTask.join();
                Long rightResult = rightTask.join();
                 
                sum = leftResult + rightResult;
            }
             
            return sum;
        }
    }
}

     本文转自sarchitect 51CTO博客,原文链接:http://blog.51cto.com/stevex/1576108,如需转载请自行联系原作者

Java ForkJoin 框架初探相关推荐

  1. WebMagic Java爬虫框架初探

    利用httpclient编写网页数据爬取有一段时间了,一直苦恼于重复的编码以及cookie的处理,一直希望有一个好用的java框架或者自己搞一个框架.可惜水平还不够格,而且也没时间安静下来抽象框架. ...

  2. java forkjoin MySQL_Java并发fork-join框架

    fork-join框架允许在几个工作进程中断某个任务,然后等待结果组合它们. 它在很大程度上利用了多处理器机器的生产能力. 以下是fork-join框架中使用的核心概念和对象. Fork Fork是一 ...

  3. Java7中的ForkJoin并发框架初探(中)——JDK中实现简要分析

    为什么80%的码农都做不了架构师?>>>    根据前文描述的Doug Lea的理论基础,在JDK1.7中已经给出了Fork Join的实现.在Java SE 7的API中,多了Fo ...

  4. 分支合并 Fork-Join 框架

    一.什么是 Fork-Join Fork/Join框架是Java7提供了的一个用于并行执行任务的框架,是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架,这种开发方法也叫分 ...

  5. JAVA并行框架:Fork/Join

    转载自 https://www.cnblogs.com/dongguacai/p/6021859.html JAVA并行框架:Fork/Join 一.背景 虽然目前处理器核心数已经发展到很大数目,但是 ...

  6. Java7任务并行执行神器:ForkJoin框架

    转载自 Java7任务并行执行神器:Fork&Join框架 Fork/Join是什么? Fork/Join框架是Java7提供的并行执行任务框架,思想是将大任务分解成小任务,然后小任务又可以继 ...

  7. ForkJoin框架源码分析(详细)

    ForkJoin简介及使用 ForkJoin框架是CompletableFuture和java8 stream使用到的框架.主要用于分片处理的场景. 可以通过自定义分片粒度来实现任务分解.并行处理数据 ...

  8. ForkJoin框架详解 一张图搞明白工作窃取(work-stealing)机制

    1 ForkJoin框架 1.1 ForkJoin框架 ForkJoinPool一种ExecutorService的实现,运行ForkJoinTask任务.ForkJoinPool区别于其它Execu ...

  9. 使用forkjoin框架分页查询所有数据的例子

    使用forkjoin框架分页查询所有数据的例子 import io.swagger.annotations.ApiOperation; import lombok.AllArgsConstructor ...

最新文章

  1. 饥荒海难机器人怎么用_饥荒:海难是一款野外生存游戏
  2. 专访 | 周涛:从窄门进最终走出宽路来
  3. 初识 Vue(18)---(非父子组件间的传值)
  4. POJ 1064 Cable master (二分答案,G++不过,C++就过了)
  5. java设计高并发内存池_高并发服务器-连接池的设计
  6. Google SVN托管和使用学习笔记
  7. SQL按字段分组取最大(小)值记录(重复记录)
  8. qq空间html倒计时,空间倒计时flash代码,有图
  9. Centos中源码安装mysql
  10. php 万能密码,万能用户名和万能密码
  11. Python汉诺塔递归算法实现
  12. Twaver-HTML5基础学习(11)形状节点(ShapeNode)
  13. centos7安装noIP-动态域名解析最佳实践
  14. 练就超强记忆力,成为最强大脑【完结】
  15. PHP Failed opening required
  16. cython安装ubuntu_Cython安装与使用入门
  17. 钉钉应用开发服务器API错误码原因及解决方法
  18. 【Python】列表生成式应用的八重境界
  19. 无人值守安装linux操作系统
  20. att格式汇编指令_ATT汇编语法简介

热门文章

  1. Java线程volatile(二)
  2. Grunt上手指南(转)
  3. bootstrapTable表格分页后,处理逻辑后刷新跳回第一页,没留在当前页的解决办法
  4. Mybatis01(结果集封装)
  5. Vue自定义组件——非单文件组件
  6. 传统动态代理实现计算器类日志功能
  7. linux11g导入10g 怎么改版本,Oracle 11g导入到10g引起的错误
  8. python 文本框位置_「每日一练」Python文本框的显示和插入
  9. java format 补足空格_11 个简单的 Java 性能调优技巧
  10. linux下vim 选择文本,删除,复制,粘贴