如何以线程安全的方式在DAO中缓存信息 [英] How to cache information in a DAO in a threadsafe manner

查看:248
本文介绍了如何以线程安全的方式在DAO中缓存信息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我经常需要为一些不经常变化的参考数据实现DAO。我有时高速缓存在DAO的集合字段中 - 因此它只加载一次,并在需要时显式更新。

I often need to implement DAO's for some reference data that doesn't change very often. I sometimes cache this in collection field on the DAO - so that it is only loaded once and explicitly updated when required.

但是,这会带来许多并发问题 - 如果另一个线程在加载或更新时尝试访问数据。

However this brings in many concurrency issues - what if another thread attempts to access the data while it is loading or being updated.

显然,这可以通过使数据的getter和setter同步来处理 - 但对于大型Web应用程序,这是一个开销。

Obviously this can be handled by making both the getters and setters of the data synchronised - but for a large web application this is quite an overhead.

我包含了一个琐碎的例子,我需要作为一个strawman。请建议其他方法来实现。

I've included a trivial flawed example of what I need as a strawman. Please suggest alternative ways to implement this.

public class LocationDAOImpl implements LocationDAO {

private List<Location> locations = null;

public List<Location> getAllLocations() {
    if(locations == null) {
        loadAllLocations();
    }
    return locations;
}

更多信息我使用Hibernate和Spring,许多技术。

For further information I'm using Hibernate and Spring but this requirement would apply across many technologies.

一些进一步的想法:

如果这不是在代码中处理 - 而是让ehcache或类似的句柄它?
有没有一个共同的模式,我错过了?
显然有很多方法可以实现,但我从来没有找到一个简单和可维护的模式。

Should this not be handled in code at all - instead let ehcache or similar handle it? Is there a common pattern for this that I'm missing? There are obviously many ways this can be achieved but I've never found a pattern that is simple and maintainable.

提前感谢!

推荐答案

如果你只是想快速滚动自己的缓存解决方案,请查看这篇关于JavaSpecialist的文章,这是对 Java Concurrency in Practice 作者: Brian Goetz

If you just want a quick roll-your own caching solution, have a look at this article on JavaSpecialist, which is a review of the book Java Concurrency in Practice by Brian Goetz.

它介绍了使用 FutureTask ConcurrentHashMap

这种方式确保只有一个并发线程触发长时间运行的计算(在您的情况下,您的数据库调用在您的DAO)。

The way this is done ensures that only one concurrent thread triggers the long running computation (in your case, your database calls in your DAO).

如果需要,您必须修改此解决方案以添加缓存过期。

You'd have to modify this solution to add cache expiry if you need it.

另一个关于自己缓存的想法是垃圾收集。如果不为缓存使用WeakHashMap,那么GC将无法释放缓存使用的内存(如果需要)。如果你缓存不常访问的数据(但是数据仍然值得缓存,因为它很难计算),那么你可能想通过使用WeakHashMap在内存不足时帮助垃圾收集器。

The other thought about caching it yourself is garbage collection. Without using a WeakHashMap for your cache, then the GC wouldn't be able to release the memory used by the cache if needed. If you are caching infrequently accessed data (but data that was still worth caching since it is hard to compute), then you might want to help out the garbage collector when running low on memory by using a WeakHashMap.

这篇关于如何以线程安全的方式在DAO中缓存信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆