+
 新版

各位大佬,帮忙看下Java中fork/join是否正确。多线程查询分页数据

黄贤达 发布于 2020/09/18 10:49
阅读 1K+
收藏 0

各位大佬,我想查询通过分页的方式查询数据库里前10页的数据,每页100条。所以想通过fork/join去异步查询,再汇总数据。请大佬帮我看看下面的写法是否有问题,我在debug的过程中发现,有些页面重复查询了,这是为什么呢?谢谢

 

public class ExportTask extends RecursiveTask<List<RechargeSummaryDTO>> {

    private static final int THRESHOLD = 1;

    //起始页
    private int startPage;
    //结束页
    private int endPage;
    private RechargeFacade rechargeFacade;
    //每页大小
    private int pageSize;
    查询条件
    private RechargeSummaryQuery query;

    public ExportTask(RechargeFacade rechargeFacade, int pageSize, int startPage, int endPage, RechargeSummaryQuery query) {
        this.rechargeFacade = rechargeFacade;
        this.startPage = startPage;
        this.endPage = endPage;
        this.pageSize = pageSize;
        this.query = query;
    }


    @Override
    protected List<RechargeSummaryDTO> compute() {
        if ((endPage - startPage) <= THRESHOLD) {
            Pageable pageable = new Pageable();
            pageable.setPageNum(endPage);
            pageable.setPageSize(pageSize);
            PageResult<RechargeSummaryDTO> rechargeSummaryDTOPageResult = rechargeFacade.rechargeSummary(pageable, query);
            return rechargeSummaryDTOPageResult.getRecords();
        } else {
            int middle = (startPage + endPage) / 2;
            ExportTask left = new ExportTask(rechargeFacade, pageSize, startPage, middle, query);
            ExportTask right = new ExportTask(rechargeFacade, pageSize, middle, endPage, query);
            left.fork();
            right.fork();
            List<RechargeSummaryDTO> leftResult = left.join();
            List<RechargeSummaryDTO> rightResult = right.join();
            leftResult.addAll(rightResult);
            return leftResult;
        }
    }
加载中
0
jzdayz
jzdayz

其实有个最简单的写法 例如查询50到100页数据

List<Object> r = IntStream.range(50, 100).parallel().mapToObj((i) -> {
    // 查询数据
    log.info("MAP");
    List<Object> rs = new ArrayList<>();
    rs.add(new Object());
    return rs;
}).collect(Collectors.toList()).stream().reduce((a, b) -> {
    log.info("REDUCE");
    a.addAll(b);
    return a;
}).orElse(Collections.emptyList());
log.info("count:{}",r.size());

stream的并行也是用的forkjointask,去做的

中间要转list,是因为上面是并行流,重新弄成了串行流,否则addAll会有问题,或者使用线程安全的list聚合

黄
黄贤达
OK。非常感谢,这方法甚好。:+1:
OSCHINA
登录后可查看更多优质内容
返回顶部
顶部