add volitile

This commit is contained in:
Looly
2020-11-26 13:58:26 +08:00
parent 994a7a49bf
commit 4cc276e665
5 changed files with 21 additions and 19 deletions

View File

@@ -14,6 +14,7 @@
* 【core 】 xml.setXmlStandalone(true)格式优化pr#1234@Github * 【core 】 xml.setXmlStandalone(true)格式优化pr#1234@Github
* 【core 】 AnnotationUtil增加setValue方法pr#1250@Github * 【core 】 AnnotationUtil增加setValue方法pr#1250@Github
* 【core 】 ZipUtil增加get方法 * 【core 】 ZipUtil增加get方法
* 【cache 】 对CacheObj等变量使用volatile关键字
### Bug修复 ### Bug修复
* 【cron 】 修复CronTimer可能死循环的问题issue#1224@Github * 【cron 】 修复CronTimer可能死循环的问题issue#1224@Github

View File

@@ -6,6 +6,7 @@ import cn.hutool.core.lang.func.Func0;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.StampedLock; import java.util.concurrent.locks.StampedLock;
/** /**
@@ -44,11 +45,11 @@ public abstract class AbstractCache<K, V> implements Cache<K, V> {
/** /**
* 命中数 * 命中数
*/ */
protected int hitCount; protected AtomicLong hitCount;
/** /**
* 丢失数 * 丢失数
*/ */
protected int missCount; protected AtomicLong missCount;
// ---------------------------------------------------------------- put start // ---------------------------------------------------------------- put start
@Override @Override
@@ -113,15 +114,15 @@ public abstract class AbstractCache<K, V> implements Cache<K, V> {
/** /**
* @return 命中数 * @return 命中数
*/ */
public int getHitCount() { public long getHitCount() {
return hitCount; return hitCount.get();
} }
/** /**
* @return 丢失数 * @return 丢失数
*/ */
public int getMissCount() { public long getMissCount() {
return missCount; return missCount.get();
} }
@Override @Override
@@ -157,15 +158,15 @@ public abstract class AbstractCache<K, V> implements Cache<K, V> {
// 不存在或已移除 // 不存在或已移除
final CacheObj<K, V> co = cacheMap.get(key); final CacheObj<K, V> co = cacheMap.get(key);
if (null == co) { if (null == co) {
missCount++; missCount.getAndIncrement();
return null; return null;
} }
if (co.isExpired()) { if (co.isExpired()) {
missCount++; missCount.getAndIncrement();
} else{ } else{
// 命中 // 命中
hitCount++; hitCount.getAndIncrement();
return co.get(isUpdateLastAccess); return co.get(isUpdateLastAccess);
} }
} finally { } finally {
@@ -318,7 +319,7 @@ public abstract class AbstractCache<K, V> implements Cache<K, V> {
final CacheObj<K, V> co = cacheMap.remove(key); final CacheObj<K, V> co = cacheMap.remove(key);
if (withMissCount) { if (withMissCount) {
// 在丢失计数有效的情况下移除一般为get时的超时操作此处应该丢失数+1 // 在丢失计数有效的情况下移除一般为get时的超时操作此处应该丢失数+1
this.missCount++; this.missCount.getAndIncrement();
} }
return co; return co;
} }

View File

@@ -1,6 +1,7 @@
package cn.hutool.cache.impl; package cn.hutool.cache.impl;
import java.io.Serializable; import java.io.Serializable;
import java.util.concurrent.atomic.AtomicLong;
/** /**
* 缓存对象 * 缓存对象
@@ -16,9 +17,9 @@ public class CacheObj<K, V> implements Serializable{
protected final V obj; protected final V obj;
/** 上次访问时间 */ /** 上次访问时间 */
private long lastAccess; private volatile long lastAccess;
/** 访问次数 */ /** 访问次数 */
protected long accessCount; protected AtomicLong accessCount;
/** 对象存活时长0表示永久存活*/ /** 对象存活时长0表示永久存活*/
private final long ttl; private final long ttl;
@@ -61,7 +62,7 @@ public class CacheObj<K, V> implements Serializable{
if(isUpdateLastAccess) { if(isUpdateLastAccess) {
lastAccess = System.currentTimeMillis(); lastAccess = System.currentTimeMillis();
} }
accessCount++; accessCount.getAndIncrement();
return this.obj; return this.obj;
} }

View File

@@ -69,21 +69,20 @@ public class LFUCache<K, V> extends AbstractCache<K, V> {
} }
//找出访问最少的对象 //找出访问最少的对象
if (comin == null || co.accessCount < comin.accessCount) { if (comin == null || co.accessCount.get() < comin.accessCount.get()) {
comin = co; comin = co;
} }
} }
// 减少所有对象访问量并清除减少后为0的访问对象 // 减少所有对象访问量并清除减少后为0的访问对象
if (isFull() && comin != null) { if (isFull() && comin != null) {
long minAccessCount = comin.accessCount; long minAccessCount = comin.accessCount.get();
values = cacheMap.values().iterator(); values = cacheMap.values().iterator();
CacheObj<K, V> co1; CacheObj<K, V> co1;
while (values.hasNext()) { while (values.hasNext()) {
co1 = values.next(); co1 = values.next();
co1.accessCount -= minAccessCount; if (co1.accessCount.addAndGet(-minAccessCount) <= 0) {
if (co1.accessCount <= 0) {
values.remove(); values.remove();
onRemove(co1.key, co1.obj); onRemove(co1.key, co1.obj);
count++; count++;

View File

@@ -819,10 +819,10 @@ public class DateUtil extends CalendarUtil {
int length = utcString.length(); int length = utcString.length();
if (StrUtil.contains(utcString, 'Z')) { if (StrUtil.contains(utcString, 'Z')) {
if (length == DatePattern.UTC_PATTERN.length() - 4) { if (length == DatePattern.UTC_PATTERN.length() - 4) {
// 格式类似2018-09-13T05:34:31Z // 格式类似2018-09-13T05:34:31Z-4表示减去4个单引号的长度
return parse(utcString, DatePattern.UTC_FORMAT); return parse(utcString, DatePattern.UTC_FORMAT);
} else if (length == DatePattern.UTC_MS_PATTERN.length() - 4) { } else if (length == DatePattern.UTC_MS_PATTERN.length() - 4) {
// 格式类似2018-09-13T05:34:31.999Z // 格式类似2018-09-13T05:34:31.999Z-4表示减去4个单引号的长度
return parse(utcString, DatePattern.UTC_MS_FORMAT); return parse(utcString, DatePattern.UTC_MS_FORMAT);
} }
} else { } else {