ITPub博客

首页 > 应用开发 > Java > 简易LruMap

简易LruMap

原创 Java 作者:壹頁書 时间:2016-10-27 12:24:01 0 删除 编辑
单位自己写的LruMap有内存泄露的问题.

自己尝试用JDK自带的结构实现一个.
功能
    1.可以设置上线,一旦到达上线,根据LRU删除数据
    2.可以设置过期时间.到期自动删除.

  1. import java.text.SimpleDateFormat;  
  2. import java.util.Calendar;  
  3. import java.util.Date;  
  4. import java.util.LinkedHashMap;  
  5. import java.util.concurrent.DelayQueue;  
  6. import java.util.concurrent.Delayed;  
  7. import java.util.concurrent.TimeUnit;  
  8. import java.util.concurrent.locks.ReadWriteLock;  
  9. import java.util.concurrent.locks.ReentrantReadWriteLock;  
  10.   
  11. public class LruMap<K, V> {  
  12.     private final LinkedHashMap<K, V> map;  
  13.     private final int capacity;  
  14.     private final DelayQueue<Node<K>> dq;  
  15.     private final ReadWriteLock lock = new ReentrantReadWriteLock();  
  16.   
  17.     public LruMap(int capacity) {  
  18.         this.capacity = capacity;  
  19.         dq = new DelayQueue<Node<K>>();  
  20.         map = new LinkedHashMap<>(capacity, 0.75f, true);  
  21.         Thread thread = new Thread(new Runnable() {  
  22.   
  23.             @Override  
  24.             public void run() {  
  25.                 while (true) {  
  26.                     try {  
  27.                         Node<K> node = dq.take();  
  28.                         lock.writeLock().lock();  
  29.                         map.remove(node.get());  
  30.                         lock.writeLock().unlock();  
  31.                           
  32.                         System.out.println("过期删除:" + node);  
  33.                         print();  
  34.                     } catch (InterruptedException e) {  
  35.                         e.printStackTrace();  
  36.                     }  
  37.   
  38.                 }  
  39.             }  
  40.         });  
  41.   
  42.         thread.setDaemon(true);  
  43.         thread.start();  
  44.     }  
  45.       
  46.     private void print(){  
  47.         System.out.println("================");  
  48.         for(K k : map.keySet()){  
  49.             System.out.print(k+",");  
  50.         }  
  51.         System.out.print("\n");  
  52.     }  
  53.   
  54.     public V get(K k) {  
  55.         lock.readLock().lock();  
  56.         V v = map.get(k);  
  57.         lock.readLock().unlock();  
  58.         print();  
  59.         return v;  
  60.     }  
  61.   
  62.     public void set(K k, V v) {  
  63.         lock.writeLock().lock();  
  64.         if (map.size() == this.capacity) {  
  65.             remove();  
  66.         }  
  67.         map.put(k, v);  
  68.         lock.writeLock().unlock();  
  69.         print();  
  70.     }  
  71.   
  72.     public void set(K k, V v, long timeout, TimeUnit unit) {  
  73.         Node<K> node = new Node<K>(k, timeout, unit);  
  74.         lock.writeLock().lock();  
  75.         if (map.size() == this.capacity) {  
  76.             remove();  
  77.         }  
  78.         map.put(k, v);  
  79.         dq.offer(node);  
  80.         lock.writeLock().unlock();  
  81.         print();  
  82.     }  
  83.   
  84.     private void remove() {  
  85.         K k = map.keySet().iterator().next();  
  86.         map.remove(k);  
  87.         System.out.println("LRU删除:" + k);  
  88.     }  
  89.   
  90.     public static void main(String[] args) throws InterruptedException {  
  91.         LruMap<Integer, Integer> map = new LruMap<>(3);  
  92.   
  93.         map.set(1, 1);  
  94.         map.set(2, 2);  
  95.         map.set(3, 3);  
  96.         // 放入第四个,将把第一个删除  
  97.         map.set(4, 4);  
  98.         // 由于访问了第二个,所以删除的是第三个  
  99.         map.get(2);  
  100.         map.set(5, 5);  
  101.   
  102.         // 测试过期时间  
  103.         map.set(5, 5, 5, TimeUnit.SECONDS);  
  104.         map.set(10, 10, 10, TimeUnit.SECONDS);  
  105.         Thread.currentThread().join();  
  106.     }  
  107. }  
  108.   
  109. class Node<K> implements Delayed {  
  110.     private long timeout;  
  111.     private long createtime;  
  112.     private K k;  
  113.   
  114.     public Node(K k, long timeout, TimeUnit unit) {  
  115.         this.k = k;  
  116.         this.timeout = unit.toNanos(timeout);  
  117.         this.createtime = System.nanoTime();  
  118.     }  
  119.   
  120.     public K get() {  
  121.         return k;  
  122.     }  
  123.   
  124.     private long now() {  
  125.         return System.nanoTime();  
  126.     }  
  127.   
  128.     @Override  
  129.     public String toString() {  
  130.         return "Key:" + this.k + ",timeout:" + TimeUnit.SECONDS.convert(timeout, TimeUnit.NANOSECONDS) + "秒";  
  131.     }  
  132.   
  133.     @Override  
  134.     public int compareTo(Delayed o) {  
  135.         Long l1 = Long.valueOf(this.getDelay(TimeUnit.NANOSECONDS));  
  136.         Long l2 = Long.valueOf(o.getDelay(TimeUnit.NANOSECONDS));  
  137.         return l1.compareTo(l2);  
  138.     }  
  139.   
  140.     @Override  
  141.     public long getDelay(TimeUnit unit) {  
  142.         return unit.convert(createtime + timeout - now(), TimeUnit.NANOSECONDS);  
  143.     }  
  144. } 

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/29254281/viewspace-2127204/ ,如需转载,请注明出处,否则将追究法律责任。

下一篇: 一次野事务排查
请登录后发表评论 登录
全部评论

注册时间:2013-10-19

  • 博文量
    620
  • 访问量
    6339934