1 package org.apache.commons.ognl.internal;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 import org.apache.commons.ognl.internal.entry.CacheEntryFactory;
27
28 import java.util.HashMap;
29 import java.util.Map;
30 import java.util.concurrent.locks.Lock;
31 import java.util.concurrent.locks.ReadWriteLock;
32 import java.util.concurrent.locks.ReentrantReadWriteLock;
33
34 public class ReentrantReadWriteLockCache<K, V>
35 implements Cache<K, V>
36 {
37 private final ReadWriteLock lock = new ReentrantReadWriteLock();
38
39 private final Lock readLock = lock.readLock();
40
41 private final Lock writeLock = lock.writeLock();
42
43 final Map<K, V> cache = new HashMap<K, V>();
44
45 private CacheEntryFactory<K, V> cacheEntryFactory;
46
47 public ReentrantReadWriteLockCache()
48 {
49 }
50
51 public ReentrantReadWriteLockCache( CacheEntryFactory<K, V> cacheEntryFactory )
52 {
53 this.cacheEntryFactory = cacheEntryFactory;
54 }
55
56 public void clear()
57 {
58 synchronized ( cache )
59 {
60 cache.clear();
61 }
62 }
63
64 public int getSize()
65 {
66 synchronized ( cache )
67 {
68 return cache.size();
69 }
70 }
71
72
73 public V get( K key )
74 throws CacheException
75 {
76 V v;
77 boolean shouldCreate;
78 readLock.lock();
79 try
80 {
81 v = cache.get( key );
82 shouldCreate = shouldCreate( cacheEntryFactory, v );
83 }
84 finally
85 {
86 readLock.unlock();
87 }
88 if ( shouldCreate )
89 {
90 try
91 {
92 writeLock.lock();
93 v = cache.get( key );
94 if ( !shouldCreate( cacheEntryFactory, v ) )
95 {
96 return v;
97 }
98 v = cacheEntryFactory.create( key );
99 cache.put( key, v );
100 return v;
101 }
102 finally
103 {
104 writeLock.unlock();
105 }
106
107 }
108
109 return v;
110 }
111
112 protected boolean shouldCreate( CacheEntryFactory<K, V> cacheEntryFactory, V v )
113 throws CacheException
114 {
115 if ( cacheEntryFactory != null )
116 {
117 if ( v == null )
118 {
119 return true;
120 }
121 }
122 return false;
123 }
124
125 public V put( K key, V value )
126 {
127 writeLock.lock();
128 try
129 {
130 cache.put( key, value );
131 return value;
132 }
133 finally
134 {
135 writeLock.unlock();
136 }
137 }
138 }