gpt4 book ai didi

Ehcache & 多线程 : how to lock when inserting to the cache?

转载 作者:行者123 更新时间:2023-12-05 06:29:50 26 4
gpt4 key购买 nike

假设我有一个多线程应用程序,其中有 4 个线程共享一个 (Eh) 缓存;缓存存储 UserProfile 对象以避免每次都从数据库中获取它们。

现在,假设所有这 4 个线程同时请求 ID=123 的同一个 UserProfile - 而且它还没有被缓存。要做的是查询数据库并将获得的 UserProfile 对象插入到缓存中,以便以后可以重用。

但是,我想要实现的是这些线程中只有一个(第一个)查询数据库并更新缓存,而其他 3 个线程等待(排队)完成...然后获取 UserProfile直接从缓存中获取 ID=123 的对象。

你通常如何实现这种场景?使用Ehcache的locking/transactions?或者更确切地说是通过这样的事情? (伪代码)

public UserProfile getUserProfile(int id) {
result = ehcache.get(id)
if (result == null) { // not cached yet
synchronized { // queue threads
result = ehcache.get(id)
if (result == null) { // is current thread the 1st one?
result = database.fetchUserProfile(id)
ehcache.put(id, result)
}
}
}
return result
}

最佳答案

这叫做 Thundering Herd问题。

锁定有效,但它非常有效,因为锁比您想要的更宽。您可以锁定单个 ID。

你可以做两件事。一种是使用 CacheLoaderWriter .它将加载丢失的条目并以正确的粒度执行锁定。这是最简单的解决方案,即使您必须实现加载程序编写器。

备选方案更为复杂。您需要某种行锁定算法。例如,您可以这样做:

private final ReentrantLock locks = new ReentrantLocks[1024];
{
for(int i = 0; i < locks.length; i)) {
locks[i] = new ReentrantLock();
}
}

public UserProfile getUserProfile(int id) {
result = ehcache.get(id)
if (result == null) { // not cached yet
ReentrantLock lock = locks[id % locks.length];
lock.lock();
try {
result = ehcache.get(id)
if (result == null) { // is current thread the 1st one?
result = database.fetchUserProfile(id)
ehcache.put(id, result)
}
} finally {
lock.unlock();
}
}
return result
}

关于Ehcache & 多线程 : how to lock when inserting to the cache?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53125061/

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