美文网首页
Controller控制并发锁解决方案

Controller控制并发锁解决方案

作者: 阳光也学会了妩媚 | 来源:发表于2022-01-25 01:03 被阅读0次

    问题描述

    针对Controller接收消息处理,过程中非常多涉及数据并发访问,造成代码重复执行的问题,比如微信支付等返回数据处理问题。

    解决方式:

    最直接的方式,就是直接一把锁搞定,即便多个请求进来都要顺序排队。但这种方式会造成系统瓶颈,是否可以有一种方案,可以根据访问对象的ID或其他唯一标识进行加锁处理,从而达到最理想的效果。

    工具如下:

    import org.springframework.stereotype.Component;
    
    import java.util.Map;
    import java.util.concurrent.ConcurrentHashMap;
    import java.util.concurrent.locks.ReentrantLock;
    
    /**
     * Created by SunYuechao on 2022/1/24 下午11:57
     * 同步锁,工具类,经典锁工具,可根据对象对controller 进行线程控制,比如根据订单进行 线程控制
     */
    @Component
    public class SynchronizedControllerByKey {
        Map<String, ReentrantLock> mutexCache = new ConcurrentHashMap<>();
    
        public void exec(String key, Runnable statement) {
            ReentrantLock mutex4Key=null;
            ReentrantLock mutexInCache;
            do {
                 if(mutex4Key!=null){
                     mutex4Key.unlock();
                 }
                 mutex4Key = mutexCache.computeIfAbsent(key, k -> new ReentrantLock());
                 mutex4Key.lock();
                 mutexInCache = mutexCache.get(key);
                /**
                 * 两种极端情况
                 * 1、mutexInCache==null  拿到这把锁被remove掉了
                 * 2、mutexInCache!=mutex4Key 不是同一把锁
                 */
            }while (mutexInCache==null || mutexInCache != mutex4Key);
            try {
                statement.run();
            } finally {
                //没有排队就
                if (mutex4Key.getQueueLength() == 0) {
                    mutexCache.remove(key);
                }
                mutex4Key.unlock();
            }
    
        }
    }
    

    使用方法:

    //引入
    @Autowired
     SynchronizedControllerByKey synchronizedControllerByKey;
    
    //使用
    synchronizedByKey.exec(key,()->{
                    //执行代码
    
            });
    

    相关文章

      网友评论

          本文标题:Controller控制并发锁解决方案

          本文链接:https://www.haomeiwen.com/subject/rggihrtx.html