RemovalNotification
实现Map.Entry接口
getCause()获取RemovalCause
1.COLLECTED: key或value被垃圾回收;
2.EXPIRED:已过期;
3.EXPLICIT:手动移除;
4.REPLACED:被替换;
5.SIZE:超过了最大限制数量。
- package bbejeck.guava.chapter6.cache;
-
- /**
- * User: Bill Bejeck
- * Date: 4/22/13
- * Time: 9:37 PM
- */
-
- import com.google.common.cache.RemovalCause;
- import com.google.common.cache.RemovalListener;
-
- public abstract class BaseRemovalListener<K, V> implements RemovalListener<K, V> {
-
- protected RemovalCause removalCause;
- protected K removedKey;
- protected V removedValue;
-
-
- public RemovalCause getRemovalCause() {
- return removalCause;
- }
-
- public K getRemovedKey() {
- return removedKey;
- }
-
- public V getRemovedValue() {
- return removedValue;
- }
- }
- package bbejeck.guava.chapter6.cache;
-
- import bbejeck.guava.common.model.TradeAccount;
- import com.google.common.cache.RemovalListener;
- import com.google.common.cache.RemovalNotification;
-
- /**
- * User: Bill Bejeck
- * Date: 4/20/13
- * Time: 11:49 PM
- */
- public class TradeAccountRemovalListener extends BaseRemovalListener
, TradeAccount> { -
-
- public void onRemoval(RemovalNotification<String, TradeAccount> notification) {
- this.removalCause = notification.getCause();
- this.removedKey = notification.getKey();
- this.removedValue = notification.getValue();
- }
- }
- package bbejeck.guava.chapter6.cache;
-
- import bbejeck.guava.common.model.Book;
- import bbejeck.guava.common.model.TradeAccount;
- import bbejeck.guava.common.service.BookServiceImpl;
- import bbejeck.guava.common.service.TradeAccountService;
- import com.google.common.base.Ticker;
- import com.google.common.cache.*;
- import org.junit.AfterClass;
- import org.junit.BeforeClass;
- import org.junit.Test;
-
- import java.util.concurrent.TimeUnit;
-
- import static org.hamcrest.CoreMatchers.is;
- import static org.junit.Assert.assertThat;
-
- /**
- * User: Bill Bejeck
- * Date: 4/20/13
- * Time: 10:17 PM
- */
- public class RemovalListenerTest {
-
- private static TradeAccountService tradeAccountService;
- private static BookServiceImpl bookService;
-
- @BeforeClass
- public static void startUpBeforeAll() {
- bookService = new BookServiceImpl();
- tradeAccountService = new TradeAccountService();
- }
-
- @AfterClass
- public static void tearDownAfterAll() throws Exception {
- bookService.shutdown();
- tradeAccountService.shutdown();
- }
-
- @Test
- public void testLoadingCacheExpireAfterWrite() throws Exception {
- TradeAccountRemovalListener removalListener = new TradeAccountRemovalListener();
- LoadingCache<String, TradeAccount> tradeAccountCache = CacheBuilder.newBuilder()
- .expireAfterWrite(5L, TimeUnit.MILLISECONDS)
- .maximumSize(5000L)
- .removalListener(removalListener)
- .ticker(Ticker.systemTicker())
- .build(new CacheLoader<String, TradeAccount>() {
- @Override
- public TradeAccount load(String key) throws Exception {
- return tradeAccountService.getTradeAccountById(key);
- }
- });
-
- //223,"Rogers, Jim",250000.12
- TradeAccount tradeAccount = tradeAccountCache.get("223");
- assertThat(tradeAccount.getBalance(), is(250000.12));
- Thread.sleep(10L);
- tradeAccountCache.get("223");
- assertThat(removalListener.getRemovalCause(), is(RemovalCause.EXPIRED));
- assertThat(removalListener.getRemovedValue(), is(tradeAccount));
- }
-
- @Test
- public void testRemovalAfterLastAccessed() throws Exception {
- BookRemovalListener bookRemovalListener = new BookRemovalListener();
- LoadingCache<String, Book> bookCache = CacheBuilder.newBuilder()
- .expireAfterAccess(10, TimeUnit.MILLISECONDS)
- .softValues()
- .recordStats()
- .removalListener(bookRemovalListener)
- .build(new CacheLoader<String, Book>() {
- @Override
- public Book load(String key) throws Exception {
- return bookService.findBookByIsbn(key);
- }
- });
-
- Book book = bookCache.get("ISBN-234567");
- assertThat(book.getAuthor(), is("Vandeley, Art"));
- assertThat(book.getIsbn(), is("ISBN-234567"));
- Thread.sleep(20);
- //Need to call again to force eviction
- Book bookII = bookCache.get("ISBN-234567");
- assertThat(bookII.getAuthor(), is("Vandeley, Art"));
- assertThat(bookII.getIsbn(), is("ISBN-234567"));
- CacheStats cacheStats = bookCache.stats();
- assertThat(cacheStats.evictionCount(),is(1l));
- assertThat(bookRemovalListener.getRemovalCause(), is(RemovalCause.EXPIRED));
- assertThat(bookRemovalListener.getRemovedKey(), is("ISBN-234567"));
- assertThat(bookRemovalListener.getRemovedValue(), is(book));
-
-
- }
-
- @Test
- public void testInvalidateBadValue() throws Exception {
- BookRemovalListener bookRemovalListener = new BookRemovalListener();
- LoadingCache<String, Book> bookCache = CacheBuilder.newBuilder()
- .expireAfterAccess(10, TimeUnit.HOURS)
- .softValues()
- .recordStats()
- .removalListener(bookRemovalListener)
- .build(new CacheLoader<String, Book>() {
- @Override
- public Book load(String key) throws Exception {
- return bookService.findBookByIsbn(key);
- }
- });
-
- Book book = bookCache.get("ISBN-234567");
- assertThat(book.getTitle(), is("Be an Architect"));
- bookCache.invalidate("ISBN-234567");
- assertThat(bookRemovalListener.getRemovalCause(), is(RemovalCause.EXPLICIT));
- assertThat(bookRemovalListener.getRemovedValue().getTitle(), is("Be an Architect"));
- }
-
- @Test
- public void testRefreshingCacheValues() throws Exception {
- TradeAccountRemovalListener removalListener = new TradeAccountRemovalListener();
- LoadingCache<String, TradeAccount> tradeAccountCache = CacheBuilder.newBuilder()
- .concurrencyLevel(10)
- .refreshAfterWrite(5L, TimeUnit.MILLISECONDS)
- .removalListener(removalListener)
- .ticker(Ticker.systemTicker())
- .recordStats()
- .build(new CacheLoader<String, TradeAccount>() {
- @Override
- public TradeAccount load(String key) throws Exception {
- return tradeAccountService.getTradeAccountById(key);
- }
- });
-
- //223,"Rogers, Jim",250000.12
- TradeAccount tradeAccount = tradeAccountCache.get("223");
- assertThat(tradeAccount.getBalance(), is(250000.12));
- Thread.sleep(10L);
- tradeAccountCache.get("223");
- CacheStats stats = tradeAccountCache.stats();
- assertThat(stats.loadSuccessCount(),is(2l));
- assertThat(removalListener.getRemovalCause(), is(RemovalCause.REPLACED));
- assertThat(removalListener.getRemovedValue(), is(tradeAccount));
- }
-
- }