ehcache 在处理并发请求时调用 LoaderWriter 是否高效?

Does ehcache calls LoaderWriter in an efficient way when dealing with concurrent requests?

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

想过这样的缓存:

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 时,缓存是否会将第二个线程置于 'wait' 直到条目 1 被加载,或者,第二个请求是否会触发(几乎)同时加载再次输入 1。也就是说,导致同一条目从 LoaderWriter 加载两次 ?

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

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

请注意,此系统与线程安全无关,您的加载程序对于不同的键仍必须是线程安全的,但与高效的资源使用有关。它假设从数据库加载比缓存命中慢得多。