是否适合使用AtomicReference.compareAndSet来设置对数据库调用结果的引用?

我正在实现一个简单的缓存,缓存存储为AtomicReference。

private AtomicReference<Map> cacheData; 

应该从数据库表中填充(延迟)缓存对象。

我提供了一种方法来将缓存数据返回给调用者,但如果数据为空(即未加载),则代码需要从数据库加载数据。 为避免同步我想到使用compareAndSet()方法:

 public Object getCacheData() { cacheData.compareAndSet(null, getDataFromDatabase()); // atomic reload only if data not set! return Collections.unmodifiableMap(cacheData.get()); } 

以这种方式使用compareAndSet是否可以。 将数据库调用作为primefaces操作的一部分? 是否比同步方法更好/更差?

非常感谢任何建议..

您没有达到预期的行为。 这个表达式:

 cacheData.compareAndSet(null, getDataFromDatabase()) 

始终首先调用getDataFromDatabase() 。 这意味着数据是否被缓存无关紧要。 如果是,您仍然调用数据库,但丢弃结果。 缓存正在运行,但性能同样很差。

请考虑一下:

 if(cacheData.get() == null) { cacheData.compareAndSet(null, unmodifiableMap(getDataFromDatabase())); } return cacheData.get()); 

它并不完美(仍然可以在开始时多次调用getDataFromDatabase() ),但是会按预期稍后工作。 我之前也移动了Collections.unmodifiableMap() ,这样你就不必一遍又一遍地包装同一个地图。

这使我们更简单的实现(不需要synchronizedAtomicReference ):

 private volatile Map cacheData; if(cacheData == null) { cacheData = unmodifiableMap(getDataFromDatabase()); } return cacheData;