All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.acyou.leo.framework.util.ConcurrentHelper Maven / Gradle / Ivy

package cn.acyou.leo.framework.util;

import cn.acyou.leo.framework.exception.ConcurrentException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.Assert;

import java.util.concurrent.ConcurrentHashMap;

/**
 * 本地并发访问工具
 *
 * 
 *    ConcurrentHelper.doWork("AAA", ()->{
 *       countTest = countTest-10;
 *   });
 * 
* @author fangyou * @version [1.0.0, 2021-11-02 17:01] */ @Slf4j public class ConcurrentHelper { private static final ConcurrentHashMap cache = new ConcurrentHashMap<>(); //标识 prefix private static final String LOCK_KEY_PREFIX = "LOCAL_LOCK:"; //默认超时时间 60S private static final long DEFAULT_TIME_OUT = 60 * 1000; /** * 获得锁 * * @param lockKey 锁定键 * @return {@link String} */ private synchronized static Long lock(String lockKey) { return lock(lockKey, DEFAULT_TIME_OUT); } /** * 获得锁 * * @param lockKey 锁定键 * @param milliSecond 毫秒 * @return {@link String} */ private synchronized static Long lock(String lockKey, long milliSecond) { Assert.notNull(lockKey, "lockKey 不能为空!"); long now = System.currentTimeMillis(); Long value = cache.get(LOCK_KEY_PREFIX + lockKey); Long lockId = now + milliSecond; if (value == null) { cache.put(LOCK_KEY_PREFIX + lockKey, lockId); return lockId; } else { if (value > now) { return null; } else { cache.put(LOCK_KEY_PREFIX + lockKey, lockId); return lockId; } } } /** * 解锁 * * @param lockKey 锁Key * @param lockId 锁标识 * @return boolean 是否成功 */ private synchronized static boolean unLock(String lockKey, Long lockId) { if (StringUtils.isEmpty(lockKey)) { return false; } if (lockId == null) { return false; } Long currentLockId = cache.get(LOCK_KEY_PREFIX + lockKey); if (currentLockId != null && currentLockId.equals(lockId)) { cache.remove(LOCK_KEY_PREFIX + lockKey); return true; } return false; } /** * 执行任务 * * @param key 锁关键词 * @param task 任务 */ public static void doWork(String key, Task task) { doWork(key, DEFAULT_TIME_OUT, task); } /** * 执行任务 * * @param key 锁关键词 * @param time 锁时间(毫秒) * @param task 任务 */ public static void doWork(String key, Long time, Task task) { Long lock = null; try { lock = ConcurrentHelper.lock(key, time); if (lock == null) { log.warn("Key:{} 正在处理中...", key); throw new ConcurrentException("正在处理中,请稍候..."); } task.run(); } finally { ConcurrentHelper.unLock(key, lock); } } /** * 执行有返回值的任务 * * @param key 锁关键词 * @param callTask 调用任务 * @return {@link T} 任务返回值 */ public static T doCallWork(String key, CallTask callTask){ Long lock = null; try { lock = ConcurrentHelper.lock(key); if (lock == null) { log.warn("Key:{} 正在处理中...", key); throw new ConcurrentException("正在处理中,请稍候..."); } return callTask.run(); } finally { ConcurrentHelper.unLock(key, lock); } } /** * 做等待循环 * * @param waitTime 等待时间 (时间秒) * @param callTask 调用任务 (返回null时重试) * @return {@link T} */ public static T doWaitLoop(int waitTime, CallTask callTask) { long current = System.currentTimeMillis(); long end = System.currentTimeMillis() + (waitTime * 1000L); while (current < end) { log.warn("循环任务中... time {} -> {}", current, end); T run = callTask.run(); if (run != null) { log.warn("循环任务获取值结束... time {} -> {}", current, end); return run; } try { Thread.sleep(500); } catch (InterruptedException e) { //ignore } current = System.currentTimeMillis(); } log.warn("循环任务未获取值结束... time {} -> {}", current, end); return null; } public interface Task { void run() throws RuntimeException; } public interface CallTask { T run() throws RuntimeException; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy