Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Thread-safe cache of one object in java

let's say we have a CountryList object in our application that should return the list of countries. The loading of countries is a heavy operation, so the list should be cached.

Additional requirements:

  • CountryList should be thread-safe
  • CountryList should load lazy (only on demand)
  • CountryList should support the invalidation of the cache
  • CountryList should be optimized considering that the cache will be invalidated very rarely

I came up with the following solution:

public class CountryList {     private static final Object ONE = new Integer(1);      // MapMaker is from Google Collections Library         private Map<Object, List<String>> cache = new MapMaker()         .initialCapacity(1)         .makeComputingMap(             new Function<Object, List<String>>() {                 @Override                 public List<String> apply(Object from) {                     return loadCountryList();                 }             });      private List<String> loadCountryList() {         // HEAVY OPERATION TO LOAD DATA     }      public List<String> list() {         return cache.get(ONE);     }      public void invalidateCache() {         cache.remove(ONE);     } } 

What do you think about it? Do you see something bad about it? Is there other way to do it? How can i make it better? Should i look for totally another solution in this cases?

Thanks.

like image 324
Igor Mukhin Avatar asked Sep 03 '10 13:09

Igor Mukhin


People also ask

How do you make an object thread-safe in Java?

Using Atomic Variable Using an atomic variable is another way to achieve thread-safety in java. When variables are shared by multiple threads, the atomic variable ensures that threads don't crash into each other.

Is cache thread-safe?

The short answer is yes they will.

How do I make my POJO class thread-safe?

Take two threads A and B for instance. Suppose A sets value to 5 and B sets it to 8 after that. Doing a get() in thread A would return 8. It should have returned 5.

How can we make an object thread-safe show with example?

1) Immutable objects are by default thread-safe because their state can not be modified once created. Since String is immutable in Java, it's inherently thread-safe. 2) Read-only or final variables in Java are also thread-safe in Java. 3) Locking is one way of achieving thread-safety in Java.


1 Answers

google collections actually supplies just the thing for just this sort of thing: Supplier

Your code would be something like:

private Supplier<List<String>> supplier = new Supplier<List<String>>(){     public List<String> get(){         return loadCountryList();     } };   // volatile reference so that changes are published correctly see invalidate() private volatile Supplier<List<String>> memorized = Suppliers.memoize(supplier);   public List<String> list(){     return memorized.get(); }  public void invalidate(){     memorized = Suppliers.memoize(supplier); } 
like image 176
Gareth Davis Avatar answered Oct 03 '22 02:10

Gareth Davis