LRU算法:
1.用一个一个有界的双向队列存储数据,队首插入数据,队尾淘汰数据
2.队列满了,可以继续往队头插入数据,为了保持队列的容量,淘汰队尾的元素
2.读取队列的一个元素,就把这个元素移动到队头。这样就实现了队尾始终是访问频率相对其他元素降低的元素,队头是访问频率高的元素
简单Redisson实现:
public class LRURedisDequeueextends Thread { private static final RedissonClient redissonClient; private linkedBlockingQueue data = new linkedBlockingQueue<>(); private final RDeque deque; private final int capacity; private AtomicInteger count; private final String name; static { redissonClient = ApplicationContextBeanGetter.getBean(RedissonClient.class); } public LRURedisDequeue(String name, int max){ this.name = name; deque = redissonClient.getDeque(name); this.capacity = max; //初始化count RMap map = redissonClient.getMap("LRU-LIST-COUNT"); if(map.isEmpty() || map.get(name)==null){ map.put(name,0); count = new AtomicInteger(0); }else{ count = new AtomicInteger(map.get(name)); } this.start(); Runtime.getRuntime().addShutdownHook(new Thread(()->{ while(!data.isEmpty()){ System.out.println("等待执行中..."); } })); } public void store(E e){ if(count.get()>=capacity){ deque.addFirst(e); deque.removeLast(); }else{ int tc = count.incrementAndGet(); if(tc<=capacity){ RBatch batch = redissonClient.createBatch(); RDequeAsync de = batch.getDeque(name); de.addFirstAsync(e); RMapAsync map = batch.getMap("LRU-LIST-COUNT"); map.putAsync(name,tc); batch.execute(); } } } //调用E的equal public E get(E e){ Iterator it = deque.iterator(); while(it.hasNext()){ E element = it.next(); if (element.equals(e)){ data.offer(element); return element; } } return null; } @Override public void run() { while(true){ E e = data.poll(); if(e!=null){ //pipeline RBatch batch = redissonClient.createBatch(); RDequeAsync queue = batch.getDeque(name); queue.removeAsync(e); queue.addFirstAsync(e); batch.execute(); } } } }
测试样例:
@Test
public void redisTest(){
//队列名和队列容量
LRURedisDequeue cache = new LRURedisDequeue<>("TEST-LPU-P",100);
List ts = new ArrayList<>();
for(int i=0;i<3;i++){
Thread t = new Thread(()->{
cache.store("1");
cache.store("2");
cache.store("3");
cache.store("a");
cache.store("b");
cache.store("c");
cache.store("1");
cache.get("a");
cache.store("p");
});
t.start();
ts.add(t);
}
for(Thread tt:ts){
try {
tt.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(redissonClient.getMap("LRU-LIST-COUNT").get("TEST-LPU-P"));
}



