基于Flux的动态批量运行任务(异步版)

Github源码

相关文章

基于Flux的动态批量运行任务(阻塞版)
基于Flux的动态批量运行任务(异步版)

应用场景

事先不确定数据的数目,但是需要并发分批处理数据(比如,查询数据库时,可边读取数据,边异步分批处理数据)。故实现基于Flux的动态批量运行任务。

调度器:决定任务在多线程、单线程还是当前线程执行。

代码实现

Maven引用Flux

        <dependency>
            <groupId>io.projectreactor</groupId>
            <artifactId>reactor-core</artifactId>
            <version>3.3.0.RELEASE</version>
        </dependency>
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Scheduler;
import reactor.core.scheduler.Schedulers;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Objects;
import java.util.function.Consumer;

/**
 * 基于Flux的动态批量运行任务(异步版)
 *
 * @param <T> the type parameter
 */
public class FluxBatchRunner<T> {
    private Scheduler scheduler;
    private int batchSize;
    private Consumer<Collection<T>> consumer;
    private Collection<T> records;

    public FluxBatchRunner(int batchSize, Consumer<Collection<T>> consumer) {
        if (batchSize <= 0) {
            throw new IllegalArgumentException();
        }
        Objects.requireNonNull(consumer);
        this.batchSize = batchSize;
        this.consumer = consumer;
        scheduler = Schedulers.parallel();
        records = new ArrayList<>(batchSize);
    }

    public FluxBatchRunner<T> setBatchSize(int batchSize) {
        this.batchSize = batchSize;
        return this;
    }

    public FluxBatchRunner<T> setScheduler(Scheduler scheduler) {
        this.scheduler = scheduler;
        return this;
    }

    /**
     * 添加数据
     *
     * @param t the t
     */
    public void add(T t) {
        records.add(t);
        if (records.size() == batchSize) {
            subscribeToMono(records);
            // reset
            records = new ArrayList<>(batchSize);
        }
    }

    /**
     * Do final.
     */
    public void doFinal() {
        if (!records.isEmpty()) {
            subscribeToMono(this.records);
        }
    }

    private void subscribeToMono(Collection<T> records) {
        Mono.just(records).subscribeOn(scheduler).subscribe(data -> consumer.accept(data));
    }
}

使用示例

public class FluxBatchRunnerTest {

    @Test
    public void doFinal() throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(5);
        FluxBatchRunner<Integer> batchRunner = new FluxBatchRunner<>(20, data -> {
            System.out.printf("begin:: thread=%s; data=%s%n", Thread.currentThread().getName(), data.toString());
            try {
                Thread.sleep(200);
                countDownLatch.countDown();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.printf("end:: thread=%s; size=%s%n", Thread.currentThread().getName(), data.size());
        });
        IntStream.range(0, 100).forEach(batchRunner::add);
        batchRunner.doFinal();
        countDownLatch.await();
    }
}

结果

在这里插入图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值