Diego
Diego

Reputation: 803

Synchronize multiple-threads to ensure only one of them caches a result (using spring cache)?

Let's say that I have a method A, which is @Cacheable, but many threads may access it at the same time with the same parameters.

I'd like to ensure that only the first thread creates the cache, to prevent all of the other thread from processing their requests.

I could use synchronized to wrap the method of course. But that would cause all of the threads would block on that method. And also, synchronized will not wrap the @Cacheable AOP.

So, is there a way using Spring out-of-the-box to implement this?

Upvotes: 0

Views: 3024

Answers (1)

John Blum
John Blum

Reputation: 7991

See the @Cacheable annotation sync attribute (Javadoc) and Reference Documentation for the same.

Also, as @dnault alluded to, it is also caching provider implementation dependent. Not all caching providers may support this option, so check that your caching provider does.

Regarding...

"I'd like to ensure that only the first thread creates the cache, to prevent all of the other thread from processing their requests."

Cache synchronization is not about synchronizing on the "creation of the cache itself", but rather about synchronizing on the entry (by key) that is cached.

A cache is a Map (i.e. a key/value store/data structure).

If I have a application service method that is conducive to caching, for example:

@Service
class UserService {


  @Cacheable(cacheNames = "UsersByName", sync = true)
  User findBy(String name) {
    ...
  }
}

Then if given...

Thread A: userService.findBy("janeDoe");

Thread B: userService.findBy("jonDoe");

Thread C: usesService.findBy("janeDoe");

Only Thread C will block and wait on the cache result computed by Thread A.

Thread B will proceed to lookup or compute the User for "jonDoe" uninterrupted.

Also note, most caching providers expect the "UsersByName" cache to already exist at application configuration/startup time.

Upvotes: 2

Related Questions