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:
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.
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.
The short answer is yes they will.
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.
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.
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); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With