Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'master' of github.com:grails/grails-core

  • Loading branch information...
commit 25ebc4c97430dadb78f799c6b58a7bfac44ef6e3 2 parents b25acc6 + 9f1052f
@graemerocher graemerocher authored
View
27 grails-web/src/main/groovy/org/codehaus/groovy/grails/web/util/CacheEntry.java
@@ -1,36 +1,49 @@
package org.codehaus.groovy.grails.web.util;
import java.security.PrivilegedAction;
+import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
*
- * Wrapper for value in side a cache that adds timestamp information
+ * Wrapper for a value inside a cache that adds timestamp information
+ * for expiration and prevents "cache storms" with a Lock.
*
- * prevents "cache storms" with a Lock
+ * JMM happens-before is ensured with AtomicReference.
+ *
+ * Objects in cache are assumed to not change after publication.
*
* @author Lari Hotari
*/
public class CacheEntry<T> {
- T value;
+ AtomicReference<T> valueRef=new AtomicReference<T>(null);
long createdMillis;
Lock writeLock=new ReentrantLock();
public CacheEntry(T value) {
- this.value = value;
+ this.valueRef.set(value);
resetTimestamp();
}
+ /**
+ * gets the current value from the entry and updates it if it's older than timeout
+ *
+ * updater is a callback for creating an updated value.
+ *
+ * @param timeout
+ * @param updater
+ * @return
+ */
public T getValue(long timeout, PrivilegedAction<T> updater) {
- if(timeout < 0 || updater==null) return value;
+ if(timeout < 0 || updater==null) return valueRef.get();
if(System.currentTimeMillis() - timeout > createdMillis) {
try {
long beforeLockingCreatedMillis = createdMillis;
writeLock.lock();
if(beforeLockingCreatedMillis == createdMillis || createdMillis == 0L) {
- value = updater.run();
+ valueRef.set(updater.run());
resetTimestamp();
}
} finally {
@@ -38,7 +51,7 @@ public T getValue(long timeout, PrivilegedAction<T> updater) {
}
}
- return value;
+ return valueRef.get();
}
private void resetTimestamp() {
Please sign in to comment.
Something went wrong with that request. Please try again.