ForkJoin 应用实战

此处例子是带返回值的多任务处理方法

1、线程池大小可配置

2、批量处理数量可配置

3、增加可配置开关

下次补充spring异步和不带返回值的forkjoin

 

package xxx.acceptance.controller;

import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;


/**
 * 受理消息Controller
 * 202005141549
 */
@RestController
@RequestMapping("/acceptMsg")
public class AcceptMsgController {

    @Resource
    private IMsgService msgService;
    @Value("${accept.pool.size:10}")
    private int ACCEPT_POOL_MAX;
    @Value("${accept.msg.max:50}")
    private int ACCEPT_MSG_MAX;
    @Value("${accept.async.switch:true}")
    private boolean asyncSwitch;

    @RequestMapping(value = "/batchAcceptMsg",produces = "application/json;charset=utf-8")
    public JsonResult batchAcceptMsg(@RequestBody AcceptMsgVo msgVo){
        //打开多线程受理开关
        if(asyncSwitch){
            return batchAcceptMsgUseForkJoin(msgVo);
        }
        List<Msg> ml = msgVo.getMsgList();
        int acceptCount = 0,     //受理条数
            sumCount = ml.size();//总条数
        long startTime =0l;
        try{
            startTime = System.currentTimeMillis();
            if(ml.size()==0){
                return JsonResult.errorResult("参数为空");
            }
            for(Msg msg:ml){
                acceptCount += msgService.updateMsg(msg,0L);
            }
        } catch (Exception e) {
            return JsonResult.errorResult("受理异常"+e.getMessage());
        }
        return JsonResult.successResult(String.format("受理成功:传入{%d}条,受理{%d}条,耗时{%d}ms",sumCount,acceptCount,System.currentTimeMillis()-startTime));
    }

    /**
     * 多任务受理
     * @param msgVo
     * @return
     */
    public JsonResult batchAcceptMsgUseForkJoin(AcceptMsgVo msgVo){
        List<Msg> ml = msgVo.getMsgList();
        int acceptCount = 0,     //受理条数
            sumCount = ml.size();//总条数
        long startTime =0l;
       try{
           startTime = System.currentTimeMillis();
           //任务调度
           ForkJoinPool pool = new ForkJoinPool(ACCEPT_POOL_MAX);
           ForkJoinTask<Integer> taskFuture =  pool.submit(new AcceptMsgForkTask(1,sumCount,ml));
           acceptCount = taskFuture.get();
       }catch (InterruptedException | ExecutionException e){
           return JsonResult.errorResult("受理异常"+e.getMessage());
       }
        return JsonResult.successResult(String.format("受理成功:传入{%d}条,受理{%d}条,耗时{%d}ms",sumCount,acceptCount,System.currentTimeMillis()-startTime));
    }

    /**
     * 分任务受理
     */
    class AcceptMsgForkTask extends RecursiveTask<Integer> {

        private Logger log = LoggerFactory.getLogger(AcceptMsgForkTask.class);
        private Integer startValue,endValue;
        private List<Msg> msgList;

        public AcceptMsgForkTask(Integer startValue , Integer endValue,List<Msg> msgListP) {
            this.startValue = startValue;
            this.endValue = endValue;
            this.msgList=msgListP;
        }

        @Override
        protected Integer compute() {
            if(endValue - startValue < ACCEPT_MSG_MAX) {
                Integer acceptCount = 0;
                for(Msg msg : msgList.subList(startValue-1,endValue)){
                    acceptCount += msgService.updateMsg(msg,0L);
                }
                return acceptCount;
            }
            else {
                AcceptMsgForkTask subTaskLeft = new AcceptMsgForkTask(startValue, (startValue + endValue) / 2,msgList);
                subTaskLeft.fork();
                AcceptMsgForkTask subTaskRight = new AcceptMsgForkTask((startValue + endValue) / 2+1, endValue,msgList);
                subTaskRight.fork();
                return subTaskLeft.join() + subTaskRight.join();
            }

        }
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梨子科技

评论后打赏必回复并帮忙解决问题

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值