设为首页 收藏本站
查看: 799|回复: 0

[经验分享] Oracle官方教程之Fork/Join

[复制链接]

尚未签到

发表于 2016-8-4 09:45:49 | 显示全部楼层 |阅读模式
  ork/join框架是ExecutorService接口的一种具体实现,目的是为了帮助你更好地利用多处理器带来的好处。它是为那些能够被递归地拆解成子任务的工作类型量身设计的。其目的在于能够使用所有可用的运算能力来提升你的应用的性能。

类似于ExecutorService接口的其他实现,fork/join框架会将任务分发给线程池中的工作线程。fork/join框架的独特之处在与它使用工作窃取(work-stealing)算法。完成自己的工作而处于空闲的工作线程能够从其他仍然处于忙碌(busy)状态的工作线程处窃取等待执行的任务。
fork/join框架的核心是ForkJoinPool类,它是对AbstractExecutorService类的扩展。ForkJoinPool实现了工作偷取算法,并可以执行ForkJoinTask任务。
基本使用方法
  使用fork/join框架的第一步是编写执行一部分工作的代码。你的代码结构看起来应该与下面所示的伪代码类似:
1if (当前这个任务工作量足够小)

2    直接完成这个任务

3else

4    将这个任务或这部分工作分解成两个部分

5    分别触发(invoke)这两个子任务的执行,并等待结果



  你需要将这段代码包裹在一个ForkJoinTask的子类中。不过,通常情况下会使用一种更为具体的的类型,或者是RecursiveTask(会返回一个结果),或者是RecursiveAction。
当你的ForkJoinTask子类准备好了,创建一个代表所有需要完成工作的对象,然后将其作为参数传递给一个ForkJoinPool实例的invoke()方法即可。
要清晰,先模糊
  想要了解fork/join框架的基本工作原理,接下来的这个例子会有所帮助。假设你想要模糊一张图片。原始的source图片由一个整数的数组表示,每个整数表示一个像素点的颜色数值。与source图片相同,模糊之后的destination图片也由一个整数数组表示。
对图片的模糊操作是通过对source数组中的每一个像素点进行处理完成的。处理的过程是这样的:将每个像素点的色值取出,与周围像素的色值(红、黄、蓝三个组成部分)放在一起取平均值,得到的结果被放入destination数组。因为一张图片会由一个很大的数组来表示,这个流程会花费一段较长的时间。如果使用fork/join框架来实现这个模糊算法,你就能够借助多处理器系统的并行处理能力。下面是上述算法结合fork/join框架的一种简单实现:
01public class ForkBlur extends RecursiveAction {

02private int[] mSource;

03private int mStart;

04private int mLength;

05private int[] mDestination;

06 

07// Processing window size; should be odd.

08private int mBlurWidth = 15;

09 

10public ForkBlur(int[] src, int start, int length, int[] dst) {

11    mSource = src;

12    mStart = start;

13    mLength = length;

14    mDestination = dst;

15}

16 

17protected void computeDirectly() {

18    int sidePixels = (mBlurWidth - 1) / 2;

19    for (int index = mStart; index < mStart + mLength; index++) {

20        // Calculate average.

21        float rt = 0, gt = 0, bt = 0;

22        for (int mi = -sidePixels; mi <= sidePixels; mi++) {

23            int mindex = Math.min(Math.max(mi + index, 0),

24                                mSource.length - 1);

25            int pixel = mSource[mindex];

26            rt += (float)((pixel & 0x00ff0000) >>16)

27                  / mBlurWidth;

28            gt += (float)((pixel & 0x0000ff00) >> 8)

29                  / mBlurWidth;

30            bt += (float)((pixel & 0x000000ff) >> 0)

31                  / mBlurWidth;

32        }

33 

34        // Reassemble destination pixel.

35        int dpixel = (0xff000000     ) |

36               (((int)rt) << 16) |

37               (((int)gt) <<  8) |

38               (((int)bt) <<  0);

39        mDestination[index] = dpixel;

40    }

41}



  接下来你需要实现父类中的compute()方法,它会直接执行模糊处理,或者将当前的工作拆分成两个更小的任务。数组的长度可以作为一个简单的阀值来判断任务是应该直接完成还是应该被拆分。
01protected static int sThreshold = 100000;

02 

03protected void compute() {

04    if (mLength < sThreshold) {

05        computeDirectly();

06        return;

07    }

08 

09    int split = mLength / 2;

10 

11    invokeAll(new ForkBlur(mSource, mStart, split, mDestination),

12              new ForkBlur(mSource, mStart + split, mLength - split,

13                           mDestination));

14}



  如果前面这个方法是在一个RecursiveAction的子类中,那么设置任务在ForkJoinPool中执行就再直观不过了。通常会包含以下一些步骤:

  • 创建一个表示所有需要完成工作的任务。
    1// source image pixels are in src

    2// destination image pixels are in dst

    3ForkBlur fb = new ForkBlur(src, 0, src.length, dst);

  • 创建将要用来执行任务的ForkJoinPool。
    1ForkJoinPool pool = new ForkJoinPool();

  • 执行任务。
    1pool.invoke(fb);

  想要浏览完成的源代码,请查看ForkBlur,其中还包含一些创建destination图片文件的额外代码。
标准实现
  除了能够使用fork/join框架来实现能够在多处理系统中被并行执行的定制化算法(如前文中的ForkBlur.java例子),在Java SE中一些比较常用的功能点也已经使用fork/join框架来实现了。在Java SE 8中,java.util.Arrays类的一系列parallelSort()方法就使用了fork/join来实现。这些方法与sort()系列方法很类似,但是通过使用fork/join框架,借助了并发来完成相关工作。在多处理器系统中,对大数组的并行排序会比串行排序更快。这些方法究竟是如何运用fork/join框架并不在本教程的讨论范围内。想要了解更多的信息,请参见Java API文档。
其他采用了fork/join框架的方法还包括java.util.streams包中的一些方法,此包是作为Java SE 8发行版中Project Lambda的一部分。想要了解更多信息,请参见Lambda Expressions一节。
  (全文完)如果您喜欢此文请点赞,分享,评论。

  • 转自:Oracle官方教程之Fork/Join

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-252625-1-1.html 上篇帖子: ORACLE学习笔记系列(14)聚合函数 下篇帖子: Oracle的基本语法——DDL & DML
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表