在处理并发请求时,ehcache是​​否以有效的方式调用LoaderWriter?

时间:2018-06-01 21:24:23

标签: ehcache ehcache-3

(上下文)我需要构建一个缓存,从数据库加载信息并使其可供应用程序使用。此数据不会在此应用程序中更改,并且会被大量线程大量使用(检索)。数据可能(很少)从另一个应用程序更改。每1小时更新一次就足够了。猜猜Ehcache会很合适,创建一个直读缓存。

考虑一下像这样的缓存:

CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder()
        .withCache("preConfigured",
                CacheConfigurationBuilder.newCacheConfigurationBuilder(Integer.class, String.class, ResourcePoolsBuilder.heap(100))
                        .withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofHours(1)))
                        .withLoaderWriter(new CacheDataProvider())).build();

cacheManager.init();

Cache<Integer, String> myCache = cacheManager.getCache("preConfigured", Integer.class, String.class);

想象一下缓存过期(1小时后),并且一个线程要求输入密钥1,并且在另一个线程询问相同的条目1之后不久。 当第一个线程要求输入1时,缓存将检查它是否已过期,并要求LoaderWriter加载条目1.

我的问题是:当LoaderWriter为第一个请求加载条目1时,缓存会将第二个线程置于“等待”,直到加载条目1,或者,第二个请求是否会再次触发(几乎)同时加载条目1 。也就是说,导致从LoaderWriter加载两次相同的条目?

1 个答案:

答案 0 :(得分:1)

缓存中的Ehcache 3 模式将在加载程序执行时阻止对给定键的所有访问。这也表明装载机性能很重要。

在您的方案中,这意味着单个请求将转到数据库,当条目在缓存中时,在第一个线程完成加载后,第二个线程将能够从缓存中读取它。

请注意,此系统与线程安全无关,您的加载器对于不同的密钥仍必须是线程安全的,但关于有效的资源使用。它假定从DB加载比缓存命中慢得多。