java 实现数据批量处理,达到一定数量或者达到一定时间去处理

实际中可能有这样的应用场景,得到一个记录不需要立即去处理它,而是等累积到一定数量时再批量处理它们


//1、批量处理通用代码

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Consumer;

public class BatchQueue {

    private final int batchSize;
    private final Consumer> consumer;
    private final int timeoutInMs;

    private AtomicBoolean isLooping = new AtomicBoolean(false);
    private BlockingQueue queue = new LinkedBlockingQueue<>();
    private ExecutorService executorService = Executors.newCachedThreadPool();

    private AtomicLong start = new AtomicLong(System.currentTimeMillis());

    public BatchQueue(int batchSize, int timeoutInMs, Consumer> consumer) {
        this.batchSize = batchSize;
        this.timeoutInMs = timeoutInMs;
        this.consumer = consumer;
    }

    public BatchQueue(int batchSize, Consumer> consumer) {
        this(batchSize, 500, consumer);
    }

    public boolean add(T t) {
        boolean result = queue.add(t);
        if(!isLooping.get() && result) {
            isLooping.set(true);
            startLoop();
        }
        return result;
    }

    public void completeAll() {
        while (!queue.isEmpty()) {
            drainToConsume();
        }
    }

    private void startLoop() {
        executorService.execute(new ExeThread());
    }

    private void drainToConsume() {
        List drained = new ArrayList<>();
        int num = queue.drainTo(drained, batchSize);
        if(num > 0) {
            consumer.accept(drained);
            start.set(System.currentTimeMillis());
        }
    }

    private class ExeThread implements Runnable {
        @Override
        public void run() {
            start = new AtomicLong(System.currentTimeMillis());
            while(true) {
                long last = System.currentTimeMillis() - start.get() ;
                if (queue.size() >= batchSize || (!queue.isEmpty() && last > timeoutInMs)) {
                    drainToConsume();
                } else if(queue.isEmpty()) {
                    isLooping.set(false);
                    break;
                }
            }
        }
    }
}

import java.util.List;
import java.util.Scanner;

/**
 * @Date 2023/6/9
 */
public class Test {
    static BatchQueue batchQueue = new BatchQueue<>(3, 5000, x -> exe(x));

    public static void main(String[] args) {
        while (true) {
            String line = new Scanner(System.in).nextLine();
            if (line.equals("done")) {
                batchQueue.completeAll();
                break;
            }
            batchQueue.add(line);
        }
    }

    private static void exe (List o) {
        System.out.println("处理数据:" + o);
    }

}

你可能感兴趣的:(java,开发语言,mybatis)