public Object retrieve(K key, int timeout) {
		Object retval = null;
		if (isCachingEnabled()) {
			CachedObject<V> co = getCachedObject(key);
			if (co == null || isCachedObjectExpired(co)) {
				misses++;
				co = new CachedObject<V>();
				co.setBeingRetrieved();
				this.storeCachedObject(key, co);
			} else if (co.getObject() != null) {
				hits++;
				retval = co.getObject();
			} else {
				//the timeout for retrieving an object is used instead of the cache timeout
				co = getCachedObjectOnceRetrievedByOtherThread(key, timeout);
				if (co == null) {
					//this could happen on a rare occasion and may not lead to problems
					delayedMisses++;
				} else if (co.getObject() == null) { // still null
					delayedMisses++;
					if (co.isExpired(timeout) && co.isBeingRetrieved()) {
						// prolongate retrieval state if cached object is not a designated null
						co.setBeingRetrieved();
					}
				} else {
					delayedHits++;
					retval = co.getObject();
				}
			}
		}
		return retval;
	}
public Object retrieve ( K key , int timeout ) { Object retval = null ; if ( isCachingEnabled ( ) ) { CachedObject < V > co = getCachedObject ( key ) ; if ( co == null || isCachedObjectExpired ( co ) ) { misses ++ ; co = new CachedObject < V > ( ) ; co . setBeingRetrieved ( ) ; this . storeCachedObject ( key , co ) ; } else if ( co . getObject ( ) != null ) { hits ++ ; retval = co . getObject ( ) ; } else { co = getCachedObjectOnceRetrievedByOtherThread ( key , timeout ) ; if ( co == null ) { delayedMisses ++ ; } else if ( co . getObject ( ) == null ) { delayedMisses ++ ; if ( co . isExpired ( timeout ) && co . isBeingRetrieved ( ) ) { co . setBeingRetrieved ( ) ; } } else { delayedHits ++ ; retval = co . getObject ( ) ; } } } return retval ; }
Retrieves an object from cache.
This method should be used if a programmer suspects bursts of requests for
a particular object.
If this is the case, the first thread will retrieve the object,
the others will wait for some time, in order to save overhead.

@param key     the key to retrieve the object by
@param timeout time in millis to wait for the first thread to retrieve an object from the original location
@return the cached object or null if it's not found