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修复
|
### 🐞Bug修复
|
||||||
* 【core 】 修复FileResource构造fileName参数无效问题(issue#1942@Github)
|
* 【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;
|
protected final V obj;
|
||||||
|
|
||||||
/** 上次访问时间 */
|
/** 上次访问时间 */
|
||||||
private volatile long lastAccess;
|
protected volatile long lastAccess;
|
||||||
/** 访问次数 */
|
/** 访问次数 */
|
||||||
protected AtomicLong accessCount = new AtomicLong();
|
protected AtomicLong accessCount = new AtomicLong();
|
||||||
/** 对象存活时长,0表示永久存活*/
|
/** 对象存活时长,0表示永久存活*/
|
||||||
private final long ttl;
|
protected final long ttl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造
|
* 构造
|
||||||
|
@@ -1,5 +1,10 @@
|
|||||||
package cn.hutool.cache.impl;
|
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;
|
import java.util.WeakHashMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -7,18 +12,112 @@ import java.util.WeakHashMap;
|
|||||||
* 对于一个给定的键,其映射的存在并不阻止垃圾回收器对该键的丢弃,这就使该键成为可终止的,被终止,然后被回收。<br>
|
* 对于一个给定的键,其映射的存在并不阻止垃圾回收器对该键的丢弃,这就使该键成为可终止的,被终止,然后被回收。<br>
|
||||||
* 丢弃某个键时,其条目从映射中有效地移除。<br>
|
* 丢弃某个键时,其条目从映射中有效地移除。<br>
|
||||||
*
|
*
|
||||||
|
* @param <K> 键类型
|
||||||
|
* @param <V> 值类型
|
||||||
* @author Looly
|
* @author Looly
|
||||||
*
|
|
||||||
* @param <K> 键
|
|
||||||
* @param <V> 值
|
|
||||||
* @author looly
|
|
||||||
* @since 3.0.7
|
* @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;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
TimedCache<MutableObj<K>, V> timedCache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构造
|
||||||
|
*
|
||||||
|
* @param timeout 超时
|
||||||
|
*/
|
||||||
public WeakCache(long 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