gpt4 book ai didi

java - 如何将对象存储在内存中并在 Max(amount, time) 之后将它们刷新到目的地

转载 作者:行者123 更新时间:2023-12-02 01:13:59 26 4
gpt4 key购买 nike

我的 Spring Boot 应用程序获取输入 Student 并需要将其写入数据库。

我可以在获取 Student 对象后立即写入数据库,但我喜欢通过在内存中累积多个学生,然后将大量 保存到数据库来提高效率>学生

因此,我正在寻找一种解决方案,能够将学生缓存最大(某些持续时间,学生数量),并且能够在达到限制后批量保存学生.

可以选择使用Thread等编写代码,但似乎这个问题之前可能已经解决了。

caffeineguava图书馆,但我仍然没有找到我要找的东西。

最佳答案

总体思路是建立一个队列,其中包含等待刷新的对象。刷新将由 2 个事件触发:按计划(超出某些持续时间)和按大小(超出队列大小)。

在纯 Java 中,可以使用 Executors.newSingleThreadScheduledExecutor() 来实现:

public abstract class FlushingCache<T> {

private final Duration maxDuration;
private final int maxSize;
private final List<T> queue = new ArrayList<>();
private final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();

public FlushingCache(Duration maxDuration, int maxSize) {
this.maxDuration = maxDuration;
this.maxSize = maxSize;
executor.scheduleWithFixedDelay(this::doFlush,
maxDuration.getSeconds(),
maxDuration.getSeconds(),
TimeUnit.SECONDS);
}

public synchronized void enqueue(T element) {
println("Enqueueing element " + element);
queue.add(element);
if (queue.size() >= maxSize) {
doFlush();
}
}

private synchronized void doFlush() {
List<T> batch = new ArrayList<>(queue);
println("Flushing batch " + batch);
flush(batch);
queue.clear();
}

// The login of flushing to DB will be implemented in the sub-classes
protected abstract void flush(List<T> batch);
}

有以下测试数据

public static void main(String[] args) {
FlushingCache<String> studentsCache = new FlushingCache<>(Duration.ofSeconds(10), 3) {
@Override
protected void flush(List<String> batch) {
println("### FLUSH TO DB " + batch);
}
};

studentsCache.enqueue("1");
studentsCache.enqueue("2");
studentsCache.enqueue("3");

studentsCache.enqueue("4");
}

private static void println(String message) {
System.out.println(LocalTime.now().withNano(0).toString() + ": " + message);
}

结果是

16:07:17: Enqueueing element 1
16:07:17: Enqueueing element 2
16:07:17: Enqueueing element 3
16:07:17: Flushing batch [1, 2, 3]
16:07:17: ### FLUSH TO DB [1, 2, 3]
16:07:17: Enqueueing element 4
16:07:27: Flushing batch [4]
16:07:27: ### FLUSH TO DB [4]

当大小达到 3 或每 10 秒时,队列将刷新到数据库。

在 Spring Boot 应用程序中,您可以使用 @Scheduled 而不是 ScheduledExecutorService

使用@EnableScheduling启用调度

@Component
public class StudentFlushingCache {

private final List<T> queue = new ArrayList<>();

@Value("${student.flushing-cache.max-size}")
private final int maxSize;

@Scheduled(
fixedDelayString = "${student.flushing-cache.fixed-delay}",
initialDelayString = "${student.flushing-cache.initial-delay}")
public void flushPeriodically() {
doFlush();
}

public synchronized void enqueue(T element) {
/* ... */
}

private synchronized void doFlush() {
/* ... */
}
}

关于java - 如何将对象存储在内存中并在 Max(amount, time) 之后将它们刷新到目的地,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58935297/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com