mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-07-21 15:09:48 +08:00
修复LRUCache移除事件监听失效
This commit is contained in:
@@ -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
|
||||
|
@@ -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());
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user