解决并发问题

来源:互联网 发布:把mac里的文件拷到u盘 编辑:程序博客网 时间:2024/06/03 06:02

一.使用redis锁

    /**
     * 智慧云-工单系统-抢单-工单ID锁key
     */
    public static final String CLOUD_LIVE_GAIN_ORDER_LOCK_ORDERID = "cloud_live_gain_order_lock_orderid_";

  // 工单ID加锁
boolean redisLockFlag = redisKeyLockUtil.tryLock(RedisKeyConstant.CLOUD_LIVE_GAIN_ORDER_LOCK_ORDERID + orderEo.getOrderId(), 2, 3 * 1000);


if (!redisLockFlag) {
logger.info("=============>企业app抢单接口   nurseId={},userId={}  lock failed", requestDto.getEmployeeId(), orderEo.getOrderId());
context.setResult(Result.getFailureResult(FailureCodeEnum.E_APP_BIZ_005.getCode(), FailureCodeEnum.E_APP_BIZ_005.getMsg()));
return false;
}


@Component
public class RedisKeyLockUtil {

private static final Logger log = LoggerFactory.getLogger(RedisKeyLockUtil.class);

    @Autowired
@Qualifier(value = "redisClientTemplate")
    private RedisClientTemplate redis;
    
    /**
     * 是否有锁权限
     *
     * @param key
     * @param expireSeconds key的过期时间
     * @param timeoutMsecs  获取锁的超时时间
     * @return
     */
    public boolean tryLock(String key, Integer expireSeconds, long timeoutMsecs) {


        try {
            while (timeoutMsecs >= 0) {
                log.info("====================>try lock key: " + key);
                Long i = redis.setnx(key, "locked", expireSeconds); //SET if key Not eXists
                if (i == 1) {
                    log.info("====================>get lock, key: " + key + " , expire in " + expireSeconds + " seconds.");
                    return true;
                }
                timeoutMsecs -= 1000;
                Thread.sleep(1000);
            }
            return false;
        } catch (Exception e) {
            log.error("key={}; expireSeconds={}, timeoutMsecs={}", key, expireSeconds, timeoutMsecs, e);
        }
        return false;
    }




}

二:使用google  RateLimiter 限流工具类

public class AddDefaultCostConfigBizImpl  {
private static final Logger log = LoggerFactory.getLogger(QueryCostItemRuleBizImpl.class);
private final RateLimiter limiter = RateLimiter.create(0.5);//创建一个具有稳定吞吐量的速率限制器。设置每秒请求数(permits)为1个

在需要阻塞的地方加上就可以了

//阻塞方式
limiter.acquire();//从速率限制器中获取一个许可(permits),超过(permits)会被阻塞,直到请求被授予。


参考网站

http://www.mincoder.com/article/2943.shtml

0 0
原创粉丝点击