View Javadoc

1   package org.apache.commons.ognl.internal;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  /*
23   * $Id: ReentrantReadWriteLockCache.java 1194954 2011-10-29 18:00:27Z mcucchiara $
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 }