我们有一个服务层,如下所示
interface StructureService {
void create(FileEntry entry, EntryType type) throws IOException;
Collection<FileEntry> getChildren(FileEntry entry) throws IOException;
void delete(FileEntry entry) throws IOException;
void rename(FileEntry file, FileEntry newFile) throws IOException;
void copy(FileEntry source, FileEntry destination) throws IOException;
EntryType getType(FileEntry entry);
long getLastModified(FileEntry entry) throws IOException;
long getSize(FileEntry entry) throws IOException;
}
我们已经创建了一个用于缓存这些服务的代理,因为数据源可能来自数据库或rpc调用。
目前,缓存实现会清除整个缓存并在修改操作后重建它。这导致竞争条件可以通过同步呼叫来解决。然而,这是非常低效的。
相反,我们想修改每个操作的结构。
我想知道是否有一个好的,最好少锁定的已知java实现可以帮助解决这个问题。
我们在谷歌应用引擎上使用memcache作为后端,因此存储每个条目与键值对可能有所帮助。
答案 0 :(得分:1)
如果您的结构是文件夹/文件树,请尝试从根到叶子获取锁定,然后执行您的操作。对每个项目使用ReadAndWriteLock。
如果您正在阅读使用readlock。如果您正在为父母编写使用读锁定,除了中间父项和项目本身。使用它们使用写锁定。
当您获得某些内容获取锁定(必要时创建它)时,抓取数据(如果不在缓存中则读取数据),执行操作并释放锁定。
类树状锁获取父项的读锁,只有被修改项的写锁可以让你进行并发访问,但在修改时可以正确锁定。
<强>样品强>
更新/ a / b / c / d
lock for a - grab read lock
lock for b - grab read lock
lock for c - gran read lock
lock for d - grab write lock
创建/删除/ a / b / c / d
lock for a - grab read lock
lock for b - grab read lock
lock for c - gran **write** lock // you are modifying c's list of files
list / a / b / c / d
lock for a - grab read lock
lock for b - grab read lock
lock for c - gran read lock
lock for d - grab read lock
注意强>
我真的不知道在GAE中实现这一点的最佳方法是什么。如果您为每个项目都有唯一的锁,它就可以工作。在GAE案例中......我不知道你是否可以拥有它。