java原生并行框架介绍

背景

最近对易企秀推荐系统框架进行了一次升级,将原有详情页的单路召回(基于内容相似性),调整为可支持基于协同、关联规则、画像标签等多路算法召回模式,召回是从海量的数据里快速拿到相对少量的数据,要快而准,为了满足基本的性能指标,这里的召回模块需要考虑支持并行执行。
在这里插入图片描述
某电商架构图参考
在这里插入图片描述

                                易企秀商品推荐框架

Fork/Join框架是JAVA7提供的一个用于并行执行任务的框架,是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架

在这里插入图片描述

框架优势

该框架采用工作窃取算法,比传统的Executor方式更加高效与简单,不需要再单独维护计数器了;工作窃取算法指的是某个线程从其他队列里窃取任务来执行。使用的场景是一个大任务拆分成多个小任务,为了减少线程间的竞争,把这些子任务分别放到不同的队列中,并且每个队列都有单独的线程来执行队列里的任务,线程和队列一一对应。但是会出现这样一种情况:A线程处理完了自己队列的任务,B线程的队列里还有很多任务要处理。A是一个很热情的线程,想过去帮忙,但是如果两个线程访问同一个队列,会产生竞争,所以A想了一个办法,从双端队列的尾部拿任务执行。而B线程永远是从双端队列的头部拿任务执行(任务是一个个独立的小任务),这样感觉A线程像是小偷在窃取B线程的东西一样。
在这里插入图片描述

简单示例

package ai.djl.examples.inference;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.RecursiveTask;

public class MyTest extends RecursiveTask<List<Integer>> {
    private int cn = 0;
    public MyTest(int a){
        this.cn = a;
    }
    public static void main(String[] args) {
        long time1 = System.currentTimeMillis();
        MyTest t1 = new MyTest(3);    // 任务1耗时600ms
        MyTest t2 = new MyTest(5);   // 任务2耗时1s
        t1.fork();
        t2.fork();
        List<Integer> l1 = t1.join();
        List<Integer> l2 = t2.join();
        l1.addAll(l2);
        System.out.println(l1+": "+(System.currentTimeMillis() - time1)); //如果串行执行,执行时间会大于1600ms
    }
    @Override
    protected List<Integer> compute() {
        try {
            Thread.sleep(cn*200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        List<Integer> ls = new ArrayList<>();
        for(int i=0; i<cn; i++){
            ls.add(i);
        }
        return ls;
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值