Java实现LRU(最近最少使用)缓存

 

  1. package com.jd.test;  
  2. import java.io.Serializable;  
  3. import java.util.LinkedHashMap;  
  4. import java.util.concurrent.locks.Lock;  
  5. import java.util.concurrent.locks.ReentrantLock;  
  6. /** 
  7.  * 缓存类(最近最少未使用) 
  8.  *  
  9.  * @author liuzhenfeng 
  10.  *  
  11.  * @param <K,V> 
  12.  */  
  13. public class LRUCache<K, V> extends LinkedHashMap<K, V> implements Serializable {  
  14.     /** 
  15.      * 缓存默认大小 
  16.      */  
  17.     public static final int DEFAULT_CAPASITY = 20;  
  18.     /** 
  19.      * 缓存实际大小 
  20.      */  
  21.     public static int CACHE_CAPASITY = DEFAULT_CAPASITY;  
  22.     /** 
  23.      * 线程同步锁 
  24.      */  
  25.     private static final Lock lock = new ReentrantLock();  
  26.     public LRUCache() {  
  27.         super(DEFAULT_CAPASITY);  
  28.         CACHE_CAPASITY = DEFAULT_CAPASITY;  
  29.     }  
  30.     public LRUCache(int size) {  
  31.         super(size);  
  32.         CACHE_CAPASITY = size;  
  33.     }  
  34.     /* 
  35.      * 清空緩存 
  36.      *  
  37.      * @see java.util.LinkedHashMap#clear() 
  38.      */  
  39.     @Override  
  40.     public void clear() {  
  41.         try {  
  42.             lock.lock();  
  43.             super.clear();  
  44.         } finally {  
  45.             lock.unlock();  
  46.         }  
  47.     }  
  48.     /* 
  49.      * 判断是否包含该对象 
  50.      *  
  51.      * @see java.util.LinkedHashMap#containsValue(java.lang.Object) 
  52.      */  
  53.     @Override  
  54.     public boolean containsValue(Object value) {  
  55.         try {  
  56.             lock.lock();  
  57.             return super.containsValue(value);  
  58.         } finally {  
  59.             lock.unlock();  
  60.         }  
  61.     }  
  62.     /* 
  63.      * 从缓存中查询对象 
  64.      *  
  65.      * @see java.util.LinkedHashMap#get(java.lang.Object) 
  66.      */  
  67.     @Override  
  68.     public V get(Object key) {  
  69.         try {  
  70.             lock.lock();  
  71.             return super.get(key);  
  72.         } finally {  
  73.             lock.unlock();  
  74.         }  
  75.     }  
  76.     /* 
  77.      * 是否删除最早未使用缓存对象 
  78.      *  
  79.      * @see java.util.LinkedHashMap#removeEldestEntry(java.util.Map.Entry) 
  80.      */  
  81.     @Override  
  82.     protected boolean removeEldestEntry(java.util.Map.Entry<K, V> eldest) {  
  83.         try {  
  84.             lock.lock();  
  85.             return this.size() > CACHE_CAPASITY;  
  86.         } finally {  
  87.             lock.unlock();  
  88.         }  
  89.     }  
  90.     /* 
  91.      * 判断缓存中是否包含该key 
  92.      *  
  93.      * @see java.util.HashMap#containsKey(java.lang.Object) 
  94.      */  
  95.     @Override  
  96.     public boolean containsKey(Object key) {  
  97.         try {  
  98.             lock.lock();  
  99.             return super.containsKey(key);  
  100.         } finally {  
  101.             lock.unlock();  
  102.         }  
  103.     }  
  104.     /* 
  105.      * 判断缓存是否为空 
  106.      *  
  107.      * @see java.util.HashMap#isEmpty() 
  108.      */  
  109.     @Override  
  110.     public boolean isEmpty() {  
  111.         try {  
  112.             lock.lock();  
  113.             return super.isEmpty();  
  114.         } finally {  
  115.             lock.unlock();  
  116.         }  
  117.     }  
  118.     /* 
  119.      * 放入缓存 
  120.      *  
  121.      * @see java.util.HashMap#put(java.lang.Object, java.lang.Object) 
  122.      */  
  123.     @Override  
  124.     public V put(K key, V value) {  
  125.         try {  
  126.             lock.lock();  
  127.             return super.put(key, value);  
  128.         } finally {  
  129.             lock.unlock();  
  130.         }  
  131.     }  
  132.     /* 
  133.      * 从缓存中删除 
  134.      *  
  135.      * @see java.util.HashMap#remove(java.lang.Object) 
  136.      */  
  137.     @Override  
  138.     public V remove(Object key) {  
  139.         try {  
  140.             lock.lock();  
  141.             return super.remove(key);  
  142.         } finally {  
  143.             lock.unlock();  
  144.         }  
  145.     }  
  146.     /* 
  147.      * 缓存大小 
  148.      *  
  149.      * @see java.util.HashMap#size() 
  150.      */  
  151.     @Override  
  152.     public int size() {  
  153.         try {  
  154.             lock.lock();  
  155.             return super.size();  
  156.         } finally {  
  157.             lock.unlock();  
  158.         }  
  159.     }  
  160. }  

 

 

 

 

重入锁(ReentrantLock)是一种递归无阻塞的同步机制。以前一直认为它是synchronized的简单替代,而且实现机制也不相差太远。不过最近实践过程中发现它们之间还是有着天壤之别。

以下是官方说明:一个可重入的互斥锁定 Lock,它具有与使用 synchronized 方法和语句所访问的隐式监视器锁定相同的一些基本行为和语义,但功能更强大。ReentrantLock 将由最近成功获得锁定,并且还没有释放该锁定的线程所拥有。当锁定没有被另一个线程所拥有时,调用 lock 的线程将成功获取该锁定并返回。如果当前线程已经拥有该锁定,此方法将立即返回。可以使用 isHeldByCurrentThread() 和 getHoldCount() 方法来检查此情况是否发生。

它提供了lock()方法:
如果该锁定没有被另一个线程保持,则获取该锁定并立即返回,将锁定的保持计数设置为 1。
如果当前线程已经保持该锁定,则将保持计数加 1,并且该方法立即返回。
如果该锁定被另一个线程保持,则出于线程调度的目的,禁用当前线程,并且在获得锁定之前,该线程将一直处于休眠状态,此时锁定保持计数被设置为 1。

 

posted @ 2015-12-24 10:09  java高级技术汇  阅读(306)  评论(0编辑  收藏  举报