mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-07-21 15:09:48 +08:00
fix bug
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
*
|
||||
### 🐞Bug修复
|
||||
* 【core 】 修复FileResource构造fileName参数无效问题(issue#1942@Github)
|
||||
* 【cache 】 修复WeakCache键值强关联导致的无法回收问题(issue#1953@Github)
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
@@ -17,11 +17,11 @@ public class CacheObj<K, V> implements Serializable{
|
||||
protected final V obj;
|
||||
|
||||
/** 上次访问时间 */
|
||||
private volatile long lastAccess;
|
||||
protected volatile long lastAccess;
|
||||
/** 访问次数 */
|
||||
protected AtomicLong accessCount = new AtomicLong();
|
||||
/** 对象存活时长,0表示永久存活*/
|
||||
private final long ttl;
|
||||
protected final long ttl;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
|
@@ -1,5 +1,10 @@
|
||||
package cn.hutool.cache.impl;
|
||||
|
||||
import cn.hutool.cache.Cache;
|
||||
import cn.hutool.core.lang.func.Func0;
|
||||
import cn.hutool.core.lang.mutable.MutableObj;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
/**
|
||||
@@ -7,18 +12,112 @@ import java.util.WeakHashMap;
|
||||
* 对于一个给定的键,其映射的存在并不阻止垃圾回收器对该键的丢弃,这就使该键成为可终止的,被终止,然后被回收。<br>
|
||||
* 丢弃某个键时,其条目从映射中有效地移除。<br>
|
||||
*
|
||||
* @param <K> 键类型
|
||||
* @param <V> 值类型
|
||||
* @author Looly
|
||||
*
|
||||
* @param <K> 键
|
||||
* @param <V> 值
|
||||
* @author looly
|
||||
* @since 3.0.7
|
||||
*/
|
||||
public class WeakCache<K, V> extends TimedCache<K, V>{
|
||||
public class WeakCache<K, V> implements Cache<K, V> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
TimedCache<MutableObj<K>, V> timedCache;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param timeout 超时
|
||||
*/
|
||||
public WeakCache(long timeout) {
|
||||
super(timeout, new WeakHashMap<>());
|
||||
this.timedCache = new TimedCache<>(timeout, new WeakHashMap<>());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int capacity() {
|
||||
return timedCache.capacity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long timeout() {
|
||||
return timedCache.timeout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(K key, V object) {
|
||||
timedCache.put(new MutableObj<>(key), object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(K key, V object, long timeout) {
|
||||
timedCache.put(new MutableObj<>(key), object, timeout);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V get(K key, boolean isUpdateLastAccess, Func0<V> supplier) {
|
||||
return timedCache.get(new MutableObj<>(key), isUpdateLastAccess, supplier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V get(K key, boolean isUpdateLastAccess) {
|
||||
return timedCache.get(new MutableObj<>(key), isUpdateLastAccess);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<CacheObj<K, V>> cacheObjIterator() {
|
||||
final Iterator<CacheObj<MutableObj<K>, V>> timedIter = timedCache.cacheObjIterator();
|
||||
return new Iterator<CacheObj<K, V>>() {
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return timedIter.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CacheObj<K, V> next() {
|
||||
final CacheObj<MutableObj<K>, V> next = timedIter.next();
|
||||
final CacheObj<K, V> nextNew = new CacheObj<>(next.key.get(), next.obj, next.ttl);
|
||||
nextNew.lastAccess = next.lastAccess;
|
||||
nextNew.accessCount = next.accessCount;
|
||||
return nextNew;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int prune() {
|
||||
return timedCache.prune();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFull() {
|
||||
return timedCache.isFull();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(K key) {
|
||||
timedCache.remove(new MutableObj<>(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
timedCache.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return timedCache.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return timedCache.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsKey(K key) {
|
||||
return timedCache.containsKey(new MutableObj<>(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<V> iterator() {
|
||||
return timedCache.iterator();
|
||||
}
|
||||
}
|
||||
|
21
hutool-cache/src/test/java/cn/hutool/cache/WeakCacheTest.java
vendored
Normal file
21
hutool-cache/src/test/java/cn/hutool/cache/WeakCacheTest.java
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
package cn.hutool.cache;
|
||||
|
||||
import cn.hutool.cache.impl.WeakCache;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class WeakCacheTest {
|
||||
|
||||
@Test
|
||||
public void removeTest(){
|
||||
final WeakCache<String, String> cache = new WeakCache<>(-1);
|
||||
cache.put("abc", "123");
|
||||
cache.put("def", "456");
|
||||
|
||||
Assert.assertEquals(2, cache.size());
|
||||
|
||||
cache.remove("abc");
|
||||
|
||||
Assert.assertEquals(1, cache.size());
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user