gpt4 book ai didi

Java 线程安全缓存,如果正在获取新缓存,则返回旧缓存

转载 作者:搜寻专家 更新时间:2023-11-01 02:06:36 25 4
gpt4 key购买 nike

我不得不涉足缓存和多线程(每个请求的线程),我是该领域的绝对初学者,所以任何帮助将不胜感激

我的要求是:

  • 缓存一个具有以太网间隔刷新或来自用户的刷新的单个大对象
  • 因为检索对象数据非常耗时所以线程安全
  • 检索对象数据时返回“旧数据”,直到有新数据可用
  • 对其进行优化

从 SO 和其他一些用户帮助我得到了这个 ATM:

** 根据 Sandeep 和 Kayaman 的建议进行编辑 **

public enum MyClass
{
INSTANCE;

// caching field
private CachedObject cached = null;

private AtomicLong lastVisistToDB = new AtomicLong();
private long refreshInterval = 1000 * 60 * 5;

private CachedObject createCachedObject()
{
return new CachedObject();
}

public CachedObject getCachedObject()
{
if( ( System.currentTimeMillis() - this.lastVisistToDB.get() ) > this.refreshInterval)
{
synchronized( this.cached )
{
if( ( System.currentTimeMillis() - this.lastVisistToDB.get() ) > this.refreshInterval)
{
this.refreshCachedObject();
}
}
}

return this.cached;
}

public void refreshCachedObject()
{
// This is to prevent threads waiting on synchronized from re-refreshing the object
this.lastVisistToDB.set(System.currentTimeMillis());

new Thread()
{
public void run()
{
createCachedObject();
// Update the actual refresh time
lastVisistToDB.set(System.currentTimeMillis());
}
}.start();
}
}

在我看来,我的代码满足了上述所有书面要求。 (但我不确定)

随着代码很快进入第三方分析,我真的很感激任何关于代码性能和盲点的意见

感谢您的帮助。

编辑:VanOekel 的回答是解决方案,因为我的代码(根据 Sandeep 和 Kayaman 的建议编辑)没有考虑用户触发的 refresh() 的影响在这个多线程环境中

最佳答案

我不会使用 Sandeep 提议的 DCL,而是使用枚举单例模式,因为它是目前惰性初始化单例的最佳方式(而且看起来比 DCL 更好)。

使用了很多不必要的变量和代码,我会简化很多。

private static Object cachedObject;
private AtomicLong lastTime = new AtomicLong();
private long refreshPeriod = 1000;

public Object get() {

if(System.currentTimeMillis() - lastTime.get() > refreshPeriod) {
synchronized(cachedObject) {
if(System.currentTimeMillis() - lastTime.get() > refreshPeriod) {
lastTime.set(System.currentTimeMillis()); // This is to prevent threads waiting on synchronized from re-refreshing the object
new Thread() {
public void run() {
cachedObject = refreshObject(); // Get from DB
lastTime.set(System.currentTimeMillis()); // Update the actual refresh time
}
}.start();
}
}
}
return cachedObject;
}

Speedwise 仍然可以改进一点,但是减少了很多不必要的复杂性。可以删除对 System.currentTimeMillis() 的重复调用,以及两次设置 lastTime。但是,让我们从这个开始吧。

关于Java 线程安全缓存,如果正在获取新缓存,则返回旧缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31338509/

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