gpt4 book ai didi

java - 同步缓存项

转载 作者:行者123 更新时间:2023-11-30 08:06:39 25 4
gpt4 key购买 nike

我正在使用类似的东西

Cache<Integer, Item> cache;

其中 Item 彼此独立并且看起来像

private static class Item {
private final int id;
... some mutable data

synchronized doSomething() {...}
synchronized doSomethingElse() {...}
}

想法是从缓存中获取项目并在其上调用同步方法。万一遗漏,可以重新创建该项目,这很好。

当一个项目从缓存中被逐出并重新创建时会出现问题,同时线程运行同步方法。一个新线程获取一个新项目并对其进行同步...因此对于单个 id,同步方法中有两个线程。失败。

有没有简单的解决方法?这是Guava Cache ,如果有帮助的话。

最佳答案

我觉得Louis的建议,用 key 上锁是最简单实用的。这是一些代码片段,在没有 Guava 库帮助的情况下,它说明了这个想法:

static locks[] = new Lock[ ... ];
static { /* initialize lock array */ }
int id;
void doSomething() {
final lock = locks[id % locks.length];
lock.lock();
try {
/* protected code */
} finally {
lock.unlock();
}
}

锁数组的大小限制了您获得的最大并行度。如果您的代码仅使用 CPU,您可以通过可用处理器的数量对其进行初始化,这是完美的解决方案。如果您的代码等待 I/O,您可能需要一个任意大的锁数组,或者您限制可以运行临界区的线程数。在这种情况下,另一种方法可能更好。

更概念层面的评论:

如果你想防止项目被逐出,你需要一种称为固定的机制。在内部,这被大多数缓存实现使用,例如用于在 I/O 操作期间阻塞。一些缓存可能会公开应用程序执行此操作的方法。

在兼容 JCache 的缓存中,有一个 EntryProcessor 的概念。 EntryProcessor 允许您以原子方式处理条目上的少量代码。这意味着缓存正在为你做所有的锁定。根据问题的范围,这可能有优势,因为这也适用于集群场景,这意味着锁定是集群范围的。

我想到的另一个想法是可否决驱逐。这是 EHCache 3 正在实现的概念。通过指定可否决驱逐政策,您可以自行实现固定机制。

关于java - 同步缓存项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34236241/

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