We could implement such map ourselves (by overriding removeEldestEntry() from LinkedHashMap or using thread that will be removing elements periodically) but the better idea is to use already existing implementation. Google's guava library (http://code.google.com/p/guava-libraries) is the solution for us.
Let's write some simple unit tests to check the API and verify behaviour:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class ConcurrentMapExampleTest { | |
private static final int TIMEOUT_IN_MILLIS = 500; | |
private static final int KEY = 1; | |
private static final String VALUE = "David de Gea"; | |
private ConcurrentMap<Integer, String> concurrentMap; | |
@Before | |
public void setUp() { | |
Cache<Integer, String> cache = CacheBuilder.newBuilder().expireAfterWrite(TIMEOUT_IN_MILLIS, TimeUnit.MILLISECONDS).build(); | |
concurrentMap = cache.asMap(); | |
} | |
@Test | |
public void shouldRemoveElementWhenTimeoutExpires() throws InterruptedException { | |
// when | |
concurrentMap.put(KEY, VALUE); | |
Thread.sleep(TIMEOUT_IN_MILLIS * 2); // wait for the element to be removed | |
// then | |
assertThat(concurrentMap.containsKey(KEY), is(false)); | |
assertThat(concurrentMap.containsValue(VALUE), is(false)); | |
} | |
@Test | |
public void shouldNotRemoveElementWhenTimeoutDoesNotExpire() throws InterruptedException { | |
// when | |
concurrentMap.put(KEY, VALUE); | |
// then | |
assertThat(concurrentMap.containsKey(KEY), is(true)); | |
assertThat(concurrentMap.containsValue(VALUE), is(true)); | |
} | |
} |
Two tests verify that added element is removed only when the timeout expires.
Thanks for sharing - this was helpful.
ReplyDelete