StepBehindCache { public T get() { T cached = cache.get(); if (cached == null) { cached = lookup.lookup(); cache.set(cached); } else { long now = System.currentTimeMillis(); if (lastLookup <= now - period) { lastLookup = now; backgroundLookup(); } } return cached; } StepBehindCache(Lookup<T> lookup, long delay);  StepBehindCache(Lookup<T> lookup); T get(); void refresh();  }
@Test (timeOut = 5000) public void testGet() { Lookup<Long> counter = new Lookup<Long>() { public synchronized Long lookup() { return value.getAndIncrement(); } }; StepBehindCache<Long> cache = new StepBehindCache<Long>(counter, 50L); Assert.assertEquals(cache.get().longValue(), 0L); for (long v = 0; v < 10; v++) { while (cache.get().longValue() != v) {} while (value.get() != v + 1) {} } }
@Test public void testWithoutRefresh() { Lookup<Long> counter = new Lookup<Long>() { public synchronized Long lookup() { return value.get(); } }; StepBehindCache<Long> cache = new StepBehindCache<Long>(counter, 0L); Assert.assertEquals(cache.get().longValue(), 0L); value.set(MAGIC); Assert.assertEquals(cache.get().longValue(), 0L); }