View Javadoc
1   package com.atlassian.cache.ehcache;
2   
3   import net.sf.ehcache.Ehcache;
4   import net.sf.ehcache.Element;
5   import net.sf.ehcache.constructs.EhcacheDecoratorAdapter;
6   
7   import java.io.Serializable;
8   import java.util.Map;
9   import java.util.concurrent.ConcurrentHashMap;
10  import java.util.function.Consumer;
11  import java.util.function.Function;
12  
13  public class SynchronizedLoadingCacheDecorator extends EhcacheDecoratorAdapter {
14  
15      private static final Object LOAD_PLACEHOLDER = new Object();
16  
17      private final Map synchronizationMap = new ConcurrentHashMap<>();
18  
19      public SynchronizedLoadingCacheDecorator(final Ehcache delegate) {
20          super(delegate);
21      }
22  
23      @SuppressWarnings("unchecked")
24      protected <V> Element synchronizedLoad(Object key, Function<Object, V> loader, Consumer<Element> postLoadProcessor) {
25          Element result;
26          V value = null;
27          try {
28              synchronizationMap.put(key, LOAD_PLACEHOLDER);
29              value = loader.apply(key);
30          } finally {
31              result = new Element(key, value);
32              synchronizationMap.computeIfPresent(key, (a, b) -> {
33                  postLoadProcessor.accept(result);
34                  return null;
35              });
36  
37          }
38          return result;
39      }
40  
41      @Override
42      public boolean remove(Serializable key, boolean doNotNotifyCacheReplicators) {
43          synchronizationMap.remove(key);
44          return super.remove(key, doNotNotifyCacheReplicators);
45      }
46  
47      @Override
48      public boolean remove(Serializable key) {
49          synchronizationMap.remove(key);
50          return super.remove(key);
51      }
52  
53      @Override
54      public boolean remove(Object key, final boolean doNotNotifyCacheReplicators) {
55          synchronizationMap.remove(key);
56          return super.remove(key, doNotNotifyCacheReplicators);
57      }
58  
59      @Override
60      public boolean remove(Object key) {
61          synchronizationMap.remove(key);
62          return super.remove(key);
63      }
64  
65      @Override
66      public void removeAll() {
67          synchronizationMap.clear();
68          super.removeAll();
69      }
70  
71      @Override
72      public void removeAll(boolean doNotNotifyCacheReplicators) {
73          synchronizationMap.clear();
74          super.removeAll(doNotNotifyCacheReplicators);
75      }
76  }