修复LRUCache移除事件监听失效

This commit is contained in:
Looly
2022-10-12 00:11:32 +08:00
parent 09e8d7c6d1
commit c12102e89b
4 changed files with 64 additions and 12 deletions

View File

@@ -1,5 +1,6 @@
package cn.hutool.cache.impl;
import cn.hutool.core.lang.mutable.Mutable;
import cn.hutool.core.map.FixedLinkedHashMap;
import java.util.Iterator;
@@ -42,7 +43,13 @@ public class LRUCache<K, V> extends ReentrantCache<K, V> {
this.timeout = timeout;
//链表key按照访问顺序排序调用get方法后会将这次访问的元素移至头部
cacheMap = new FixedLinkedHashMap<>(capacity);
final FixedLinkedHashMap<Mutable<K>, CacheObj<K, V>> fixedLinkedHashMap = new FixedLinkedHashMap<>(capacity);
fixedLinkedHashMap.setRemoveListener(entry -> {
if(null != listener){
listener.onRemove(entry.getKey().get(), entry.getValue().getValue());
}
});
cacheMap = fixedLinkedHashMap;
}
// ---------------------------------------------------------------- prune

View File

@@ -3,11 +3,13 @@ package cn.hutool.cache;
import cn.hutool.cache.impl.LRUCache;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 见https://github.com/dromara/hutool/issues/1895<br>
@@ -20,7 +22,7 @@ public class LRUCacheTest {
@Ignore
public void putTest(){
//https://github.com/dromara/hutool/issues/2227
LRUCache<String, String> cache = CacheUtil.newLRUCache(100, 10);
final LRUCache<String, String> cache = CacheUtil.newLRUCache(100, 10);
for (int i = 0; i < 10000; i++) {
//ThreadUtil.execute(()-> cache.put(RandomUtil.randomString(5), "1243", 10));
ThreadUtil.execute(()-> cache.get(RandomUtil.randomString(5), ()->RandomUtil.randomString(10)));
@@ -30,15 +32,15 @@ public class LRUCacheTest {
@Test
public void readWriteTest() throws InterruptedException {
LRUCache<Integer, Integer> cache = CacheUtil.newLRUCache(10);
final LRUCache<Integer, Integer> cache = CacheUtil.newLRUCache(10);
for (int i = 0; i < 10; i++) {
cache.put(i, i);
}
CountDownLatch countDownLatch = new CountDownLatch(10);
final CountDownLatch countDownLatch = new CountDownLatch(10);
// 10个线程分别读0-9 10000次
for (int i = 0; i < 10; i++) {
int finalI = i;
final int finalI = i;
new Thread(() -> {
for (int j = 0; j < 10000; j++) {
cache.get(finalI);
@@ -49,7 +51,7 @@ public class LRUCacheTest {
// 等待读线程结束
countDownLatch.await();
// 按顺序读0-9
StringBuilder sb1 = new StringBuilder();
final StringBuilder sb1 = new StringBuilder();
for (int i = 0; i < 10; i++) {
sb1.append(cache.get(i));
}
@@ -58,10 +60,29 @@ public class LRUCacheTest {
// 新加11此时0最久未使用应该淘汰0
cache.put(11, 11);
StringBuilder sb2 = new StringBuilder();
final StringBuilder sb2 = new StringBuilder();
for (int i = 0; i < 10; i++) {
sb2.append(cache.get(i));
}
Assert.assertEquals("null123456789", sb2.toString());
}
@Test
public void issue2647Test(){
final AtomicInteger removeCount = new AtomicInteger();
final LRUCache<String, Integer> cache = CacheUtil.newLRUCache(3,1);
cache.setListener((key, value) -> {
// 共移除7次
removeCount.incrementAndGet();
//Console.log("Start remove k-v, key:{}, value:{}", key, value);
});
for (int i = 0; i < 10; i++) {
cache.put(StrUtil.format("key-{}", i), i);
}
Assert.assertEquals(7, removeCount.get());
Assert.assertEquals(3, cache.size());
}
}