package com.yanzuoguang.redis; import com.alicp.jetcache.Cache; import com.yanzuoguang.util.thread.ThreadHelper; import java.util.concurrent.TimeUnit; /** * 运行函数 * * @author 颜佐光 */ public class CacheLock<T, M> implements Runnable { /** * 是否执行标记 */ private boolean runFlag = false; /** * 缓存对象 */ private final Cache<T, M> cache; /** * Redis 锁定时间(豪秒) */ private final int lockTime; /** * 每次等待时间(毫秒) */ private final int waitUnitTime; /** * 关键字 */ private final T key; /** * 执行函数 */ private final Runnable funcWait; /** * 执行函数 */ private Runnable func; /** * 等待次数 */ private int waitCount; /** * 构造函数 * * @param cache 缓存对象 * @param lockTime 锁定时间 * @param waitUnitTime 等待单位 * @param key 关键字 */ public CacheLock(Cache<T, M> cache, int lockTime, int waitUnitTime, T key) { this(cache, lockTime, waitUnitTime, key, null, null); } /** * 构造函数 * * @param cache 缓存对象 * @param lockTime 锁定时间 * @param waitUnitTime 等待单位 * @param key 关键字 * @param func 执行函数 */ public CacheLock(Cache<T, M> cache, int lockTime, int waitUnitTime, T key, Runnable func) { this(cache, lockTime, waitUnitTime, key, null, func); } /** * 构造函数 * * @param cache 缓存对象 * @param lockTime 锁定时间 * @param waitUnitTime 等待单位 * @param key 关键字 * @param funcWait 等待期间执行的函数 * @param func 执行函数 */ public CacheLock(Cache<T, M> cache, int lockTime, int waitUnitTime, T key, Runnable funcWait, Runnable func) { this.cache = cache; this.lockTime = lockTime; this.waitUnitTime = waitUnitTime; this.key = key; this.funcWait = funcWait; this.func = func; } /** * 等待次数 * * @return 等待次数 */ public int getWaitCount() { return waitCount; } /** * 开始执行,每个关键字会等待其他关键字执行完成后执行 * * @param func 运行函数 */ public void run(Runnable func) { this.func = func; this.run(); } /** * 开始执行,每个关键字会等待其他关键字执行完成后执行 */ @Override public void run() { if (this.func == null) { return; } // 需要运行的函数 do { // 开启唯一性锁,防止多人运行同一关键字的函数 cache.tryLockAndRun(key, lockTime, TimeUnit.SECONDS, this::funcRun); // 假如没有运行,则等待50毫秒后继续运行 if (!runFlag) { this.waitCount++; ThreadHelper.sleep(waitUnitTime); } } while (!runFlag); } private void funcRun() { try { if (this.waitCount > 0 && this.funcWait != null) { funcWait.run(); } if (this.func != null) { func.run(); } } finally { runFlag = true; } } /** * 开始执行,每个关键字会等待其他关键字执行完成后执行 * * @param cache 缓存对象 * @param lockTime 锁定时间 * @param waitUnitTime 等待单位 * @param key 关键字 * @param func 执行函数 */ public static <T, M> void run(Cache<T, M> cache, int lockTime, int waitUnitTime, T key, Runnable func) { run(cache, lockTime, waitUnitTime, key, null, func); } /** * 开始执行,每个关键字会等待其他关键字执行完成后执行 * * @param cache 缓存对象 * @param lockTime 锁定时间 * @param waitUnitTime 等待单位 * @param key 关键字 * @param func 执行函数 */ public static <T, M> void run(Cache<T, M> cache, int lockTime, int waitUnitTime, T key, Runnable funcWait, Runnable func) { CacheLock lock = new CacheLock(cache, lockTime, waitUnitTime, key, funcWait, func); lock.run(); } }