/**
 * 
 */
package com.trendrr.oss.concurrent;

import java.util.Date;
import java.util.concurrent.atomic.AtomicReference;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


/**
 * An object that will be lazily initialized, and reinitialize every X millis
 * 
 * 
 * @author Dustin Norlander
 * @created Dec 6, 2010
 * 
 */
public abstract class ReinitObject<T> {

	protected Log log = LogFactory.getLog(ReinitObject.class);
	
	PeriodicLock lock = null;
	AtomicReference<T> ref = new AtomicReference<T>();
	
	public ReinitObject(long millisBetweenInit) {
		lock = new PeriodicLock(0, millisBetweenInit);
	}
	
	public abstract T init();
	
	public T get() {
		if (lock.lockOrWait()) {
			try {
				ref.set(this.init());	
			} finally {
				lock.unlock();
			}
		}
		return ref.get();
	}
	
	/**
	 * passively looks to see if this object needs to be re-initialized
	 * @return
	 */
	public boolean isExpired() {
		return lock.getNextUnlock().getTime() < new Date().getTime();
	}
	
	/**
	 * clears the initialized object if it is expired.
	 */
	public void clearIfExpired() {
		if (lock.lockOrWait()) {
			try {
				ref.set(null);	
			} finally {
				lock.unlock();
			}
		}
		lock.lockUntil(new Date());
	}
}

@@ -683,24 +683,128 @@
 c T get() %7B%0A
+%09%09if (ref.get() == null) %7B%0A%09%09%09//we block if the object is unitialized.  otherwise we skip while initia%0A%09
 %09%09if (lock.l
@@ -810,32 +810,33 @@
 lockOrWait()) %7B%0A
+%09
 %09%09%09try %7B%0A%09%09%09%09ref
@@ -824,32 +824,33 @@
 %7B%0A%09%09%09%09try %7B%0A%09%09%09%09
+%09
 ref.set(this.ini
@@ -855,24 +855,25 @@
 nit());%09%0A%09%09%09
+%09
 %7D finally %7B%0A
@@ -864,32 +864,33 @@
 %09%09%09%09%7D finally %7B%0A
+%09
 %09%09%09%09lock.unlock(
@@ -891,25 +891,237 @@
 nlock();%0A%09%09%09
-%7D
+%09%7D%0A%09%09%09%7D%0A%09%09%7D else %7B%0A%09%09%09// else we return the old results while the new ones are being initialized%0A%09%09%09if (lock.lockOrSkip()) %7B%0A%09%09%09%09try %7B%0A%09%09%09%09%09ref.set(this.init());%09%0A%09%09%09%09%7D finally %7B%0A%09%09%09%09%09lock.unlock();%0A%09%09%09%09%7D%0A%09%09%09%7D%0A%09%09%09
 %0A%09%09%7D%0A%09%09retur

Make reinit object non-blocking as long as there is a non-null value present