gpt4 book ai didi

java - 在多线程 Java 应用程序中创建缓存的深拷贝

转载 作者:太空宇宙 更新时间:2023-11-04 09:51:12 24 4
gpt4 key购买 nike

设置

我有一个多线程 Java 应用程序,每秒将接收 200-300 个请求,以对请求中收到的输入执行任务“A”(大约需要 30 毫秒)。

应用程序有一个缓存(最大大小 = 1MB),每个线程都会读取该缓存以在接收到的输入上执行任务“A”:

public class DataProvider() {

private HashMap<KeyObject, ValueObject> cache;

private Database database;

// Scheduled to run in interval of 15 seconds by a background thread
public synchronized void updateData() {
this.cache = database.getData();
}

public HashMap<KeyObject, ValueObject> getCache() {
return this.cache;
}

}

KeyObject 和 ValueObject 是 POJO。 ValueObject 包含另一个 POJO 的 List。

对于收到的每个请求,任务都按以下方式完成:

public class TaskExecutor() {

private DataProvider dataProvider;

public boolean doTask(final InputObject input) {
final HashMap<KeyObject, ValueObject> data = dataProvider.getCache(); // shallow copy I think
// Do Task 'A' using data
}

}

问题

其中一个线程开始使用缓存中的数据“d1”在时间戳“t”处执行任务“A”。在时间“t + t1”,缓存数据更新为“d2”。线程现在开始使用数据“d2”来完成任务的其余部分。任务在“t+t1+t2”完成。使用不同的数据完成了一半的任务。这将导致任务结果无效。

当前方法

每个线程都会创建缓存的深层复制,然后使用深层复制来执行任务,使用以下方法之一(性能最佳)来执行深层复制:

How do you make a deep copy of an object in Java?

Deep clone utility recommendation

限制

  1. 使用深层复制进行克隆将创建数千个对象,这可能会导致 JVM 崩溃。

  2. 所有克隆方法在性能方面看起来都不太好。

最佳答案

对于您的用例,从 database.getData(); 返回新的缓存是更好的选择。因为如果您选择这种方式,您只需在 15 秒内创建一次新的缓存对象。如果您选择在每个任务中克隆缓存,则必须在 15 秒内创建 4501 个缓存对象。显然返回新的缓存对象是正确的选择。

如果您提供的代码与您的项目中的代码相同,我相信 database.getData(); 方法会更改单个缓存对象的内容,而不是返回一个新的。如果您从此方法返回一个新的缓存对象,您的问题将得到解决。

关于java - 在多线程 Java 应用程序中创建缓存的深拷贝,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54723150/

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