• 0
  • 0
分享

最近在看一本15年出版的《Java并发编程的艺术》一书,其中看到并发编程时间部分的ForkJoinPool功能时,突然发现这个功能实际使用上就是把一个大任务分成多个小的子任务,然后使用多个线程完成。

这个场景跟我之前写过的自定义Java自定义异步功能实践有点异曲同工之妙,只不过这里有有个子任务的概念,多个任务执行结果是具有相关性的。资料指出ForkJoinPool比较适合计算密集型的任务。

在性能测试中QPS取样器和RT取样器中,有这样一个使用场景,在用例执行过程中,我想了解一下当前用例执行的QPS和RT信息,就需要有个触发开关,开始收集这些数据,等某一个终止条件被触发,结束收集,然后计算结果。在用例QPS超过10万的情况下,单次收集的数据可能会超过100万,计算QPS和RT就非常适合ForkJoinPool来完成。

如果一直实时展示或者上报这些信息的话,也可以使用ForkJoinPool来完成计算功能。这里还有另外的方案来实现,如果只是得到QPS和RT数据的话,比ForkJoinPool更加合适,这里先不分享了。

ForkJoinPool API相比较ExecutorService还是比较简单的。主要的功能3个:创建任务的ForkJoinPool、创建任务分配规则和收集任务结果。

下面我以一个数组求和的Demo演示一下ForkJoinPool的功能。

首先我们需要定义一个ForkJoinPool,通常使用java.util.concurrent.ForkJoinPool#ForkJoinPool(int)或者java.util.concurrent.ForkJoinPool#commonPool这两个方法其中之一,如果你使用JDK 7及以前的版本,第二个API是不存在的。

翻看源码之后,看起来ForkJoinPool构造方法参数还是挺多的,如果都要自定义比较麻烦也是没多大必要的,所以我就选上面提到的第一种API来创建ForkJoinPool。

然后我们要创建一个任务类实现任务分配规则,首先继承java.util.concurrent.RecursiveTask实现java.util.concurrent.RecursiveTask#compute方法。

拆分任务的思路如下:使用两个int属性,标记List中需要求和片段索引。这样每次分配任务的时候,只需要改变索引值即可。将一个很长的List求和分成N个小片段求和。

类代码设计如下:

import com.funtester.frame.SourceCode
import groovy.util.logging.Log4j2

import java.util.concurrent.ForkJoinPool
import java.util.concurrent.RecursiveTask

@Log4j2
class ForkJoinT extends RecursiveTask<Integer> {

    static def data = 1..100 as List

    int start
    int end

    ForkJoinT(int start, int end) {
        this.start = start
        this.end = end
    }

    @Override
    protected Integer compute() {
        if (end - start < 5) {
            sum(start, end)
        } else {
            def middle = ((start + end) / 2) as int
            def left = new ForkJoinT(start, middle)
            def right = new ForkJoinT(middle + 1, end)
            left.fork()
            right.fork()
            left.join() + right.join()
        }
    }

    /**
     * 片段求和
     * @param i
     * @param k
     * @return
     */
    static def sum(int i, int k) {
        SourceCode.range(i, k + 1).map(data::get).sum()
    }

}

总体感觉java.util.concurrent.RecursiveTask#compute方法写起来有点像递归,思路明确了以后还是很流畅的。

先来个高斯求和,下面是测试代码:

    static void main(String[] args) {
        def pool = new ForkJoinPool(5)
        def t = new ForkJoinT(0, data.size() - 1)
        pool.submit(t)
        log.info("sum: {}", t.get())
    }

控制台输出:

22:30:42.725 main sum: 5050

性能方面等我先研究一波JMH之后再来。


  • 【留下美好印记】
    赞赏支持
登录 后发表评论
+ 关注

热门文章

    最新讲堂

      • 推荐阅读
      • 换一换
          • 第一阶段:API自动化之前的想法是:通过API创建数据,访问数据,进行数据操作,存储数据库,通过模拟前端的操作来想象API的访问流程。然后,验证数据库是否存储正确。后来发现该想法流程就是错误的。问题:1、模拟前端的操作需要对每个前端操作后调用的API非常熟悉,这已经超过了测试的范围,属于开发的范畴。2、每个API的集成测试应该是独立的,有顺序的对API的测试使得API之间存在相互依赖的关系。然而每个API的正确性并不能保证。3、API本身是具有很强的独立性,不应该通过前端模拟操作来对其进行相对的验证,操作逻辑应该由前端负责。总结:1、使得API具有健壮性,对正常的数据传输和异常的数据传输,服务...
            9 9 1493
            分享
          • 摘要:在测试自动化中采用机器学习驱动的自修复技术可以防止松散的测试,减少测试失败,并节省代码维护时间。自修复是在DevOps模型中成功执行连续测试的基本因素之一。在敏捷方法中,应用程序的构建非常迅速,并且在初始开发过程中经常会发生更改。在持续测试中,自动化测试作为软件交付管道的一部分执行,以提供与软件发布候选版本相关的业务风险的即时反馈。在DevOps中,持续测试对于提高质量、降低成本和加速发布非常重要。由于持续测试是CI/CD管道的一部分,所以在代码开发的早期就可以发现问题。它帮助开发人员确定何时以及如何发布新的更改。本文将探讨具有自修复功能的持续测试如何将测试提升到下一个层次。可以减少自动...
            1 0 473
            分享
          •   近日有网友在发布视频称“在车内和司机聊收入被滴滴弹窗提醒”,对此,滴滴出行进行了官方回应。  滴滴称,经过与司乘双方沟通核实,以及对系统后台仔细排查后证实,网上相关传闻均为谣言。在该行程中,滴滴 App 并未出现所谓的弹窗提醒,更未就司乘交流内容有任何语音播报或提醒。目前该谣言的原发作者已删除不实内容。  滴滴还表示,车内录音录像会识别司机是否分心驾驶、疲劳驾驶,也会针对一些违法犯罪风险进行系统识别。同时,系统会不定时提醒司机和乘客不要泄露个人联系方式,呼吁司乘保护好账户信息等个人隐私,谨防诈骗。但绝不存在视频博主编造称“车内司乘聊收入会被滴滴弹窗提醒”等情况。  滴滴补充道,公司意识到滴...
            0 0 584
            分享
          • 小程序测试过程中,不知道大家有没有碰到一个问题,打开了很多页面之后,小程序操作突然卡卡住,就没有任何反应了。在之前项目的小程序测试过程中很多次都碰到了这种情况,开发的解释从来都是说,被微信限制了。但是自己总觉得需要想办法去解决,所以还是决定自行去学习分析下这种情况。在小程序中,打开一个新的页面其实就是创建了一个新的View对象,一层层叠加的。当点击页面的回退按钮就是把当前页面关闭。小程序页面栈的上限是10个,这个过程中就很有可能会碰到这样一个问题,就是我最一开始说的打开页面的数量过多,达到10个页面后,就不能再打开新的页面。在某些产品功能要求下,比如一个学员正在学习一个课程,在课程详情页底部一...
            1 0 7526
            分享
          • 读者提问:我们公司的项目一个功能打一个版本分支,按理来说开发改问题的时候我们可以测其他功能的,但是开发又说不行。这样比较耽误测试时间,影响项目正常上线,不知道这是什么原因是造成的呢 ?阿常回答:建议增加一套开发环境通常每个开发会有自己的功能特性分支,然后有一个主分支是对应生产环境,另一个分支对应测试环境。猜测你们是缺少开发环境的,所以开发验功能只能在测试环境操作,这就耽误了测试人员验证其他功能。阿常碎碎念:以上问答始发于 2022/3/24 「软件测试圈」,来源于小布丁向阿常的提问
            0 0 1016
            分享
      • 51testing软件测试圈微信