update 优化使用分布式缓存,以及分布式锁处理

This commit is contained in:
AprilWind 2024-08-09 10:50:01 +08:00
parent ed5127647c
commit bf6b3f9b86

View File

@ -1,12 +1,19 @@
package org.dromara.common.core.utils; package org.dromara.workflow.utils;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import com.baomidou.lock.LockInfo;
import com.baomidou.lock.LockTemplate;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.dromara.common.core.constant.GlobalConstants;
import org.dromara.common.core.utils.SpringUtils;
import org.dromara.common.redis.utils.RedisUtils;
import java.util.*; import java.util.Calendar;
import java.util.concurrent.ConcurrentHashMap; import java.util.Collections;
import java.util.concurrent.locks.ReentrantLock; import java.util.Date;
import java.util.List;
/** /**
* 工作日工具类 * 工作日工具类
@ -16,8 +23,8 @@ import java.util.concurrent.locks.ReentrantLock;
@NoArgsConstructor(access = AccessLevel.PRIVATE) @NoArgsConstructor(access = AccessLevel.PRIVATE)
public class WorkDaysUtils { public class WorkDaysUtils {
private static final Map<Integer, Integer[]> DAYS_IN_YEARS = new ConcurrentHashMap<>(); private static final String DAYS_IN_YEARS_KEY = GlobalConstants.GLOBAL_REDIS_KEY + "DAYS_IN_YEARS:";
private static final ReentrantLock LOCK = new ReentrantLock(); private static final LockTemplate LOCK_TEMPLATE = SpringUtils.getBean(LockTemplate.class);
//工作日 //工作日
public static final int WORKDAY = 0; public static final int WORKDAY = 0;
//休息日 //休息日
@ -124,10 +131,10 @@ public class WorkDaysUtils {
} }
/** /**
* 清空所有年份的数据 * 删除指定年份的数据
*/ */
public static void clearAllData() { public static void clearData(Integer year) {
DAYS_IN_YEARS.clear(); RedisUtils.deleteObject(DAYS_IN_YEARS_KEY + year);
} }
/** /**
@ -137,25 +144,24 @@ public class WorkDaysUtils {
* @return 表示一年中每一天的状态数组0 表示工作日1 表示周末 * @return 表示一年中每一天的状态数组0 表示工作日1 表示周末
*/ */
private static Integer[] daysInYear(Integer year) { private static Integer[] daysInYear(Integer year) {
// 先检查缓存 String key = DAYS_IN_YEARS_KEY + year;
if (DAYS_IN_YEARS.containsKey(year)) { Integer[] daysInYears = RedisUtils.getCacheObject(key);
return DAYS_IN_YEARS.get(year); if (ArrayUtil.isNotEmpty(daysInYears)) {
return daysInYears;
} }
LockInfo lock = LOCK_TEMPLATE.lock(key);
// 如果缓存中不存在则进行加锁
LOCK.lock();
try { try {
// 再次检查缓存防止在等待锁期间其他线程已经生成了数据 // 再次检查缓存防止缓存穿透
if (DAYS_IN_YEARS.containsKey(year)) { daysInYears = RedisUtils.getCacheObject(key);
return DAYS_IN_YEARS.get(year); if (ArrayUtil.isNotEmpty(daysInYears)) {
return daysInYears;
} }
// 如果年份数据不存在则生成指定年份的数据 // 如果年份数据不存在则生成指定年份的数据
Integer[] daysArray = generateDaysArray(year); Integer[] daysArray = generateDaysArray(year);
DAYS_IN_YEARS.put(year, daysArray); RedisUtils.setCacheObject(key, daysArray);
return daysArray; return daysArray;
} finally { } finally {
LOCK.unlock(); LOCK_TEMPLATE.releaseLock(lock);
} }
} }