ReentrantLock处理简单的等待返回场景

这几天遇到了一个稍显特殊的场景,主要提供能力给外部接口,大概如下
在这里插入图片描述

逻辑大概如下:
1 外部调用服务端接口,服务端发送指令到设备端
2 服务端等待,设备端处理完返回接口到服务端,服务端返回结果给外部接口
所以,看到这里,这个时候由外部接口注册回调是最合适的,但是因为对方业务,不能这么做.所以考虑使用ReentrantLock.
综合设计如下:
接口参数携带唯一值,服务端根据唯一值生成ReentrantLock,由该次请求产生的ReentrantLock对象,生成对应的condition即可.

/**
     * key 为orderId
     */
    private static Map<String, AwtReceiveSignRequest> requestMap = new ConcurrentHashMap<>(16);

    private final ConcurrentHashMap<String, ReentrantLock> locks = new ConcurrentHashMap<>(16);

    private final ConcurrentHashMap<ReentrantLock, Condition> conditions = new ConcurrentHashMap<>(16);
    
	@Override
    public AwtSendSignResponse sendSignToDevice(AwtSendSignRequest request) {
    
        AwtSendSignResponse response = null;
        ReentrantLock lock = getLockForKey(request.getOrderId());
        Condition condition = getConditionForLock(lock);
        lock.lock();
        try {
            /**
            业务逻辑处理
            */
            /*
            等待结果返回,或超时就返回
            */
        
            boolean await = condition.await(20, TimeUnit.SECONDS);

            AwtReceiveSignRequest receiveSignRequest = requestMap.get(request.getOrderId());
            response = new AwtSendSignResponse();
           
        } catch (Exception e) {
            log.info("receive sign error :{}", e.getMessage());
            return response;
        } finally {
            lock.unlock();
            requestMap.remove(request.getOrderId());
            locks.remove(request.getOrderId());
            conditions.remove(lock);
        }
        return response;
    }

	//接受返回消息,接收到就放开阻塞
    @Override
    public void receiveMessage(AwtReceiveSignRequest request) {
        log.info("received device callBack msg :{}", JsonUtils.toJson(request));
        ReentrantLock lock = getLockForKey(request.getOrderId());
        Condition condition = getConditionForLock(lock);
        lock.lock();
        try {
            requestMap.put(request.getOrderId(), request);
            condition.signalAll();
        } catch (Exception e) {
            log.info("receive msg fail ,cause ", e.getMessage());
        } finally {
            lock.unlock();
        }
    }


    private ReentrantLock getLockForKey(String key) {
        ReentrantLock lock = new ReentrantLock();
        ReentrantLock previous = (ReentrantLock) this.locks.putIfAbsent(key, lock);
        return previous == null ? lock : previous;
    }

    private Condition getConditionForLock(ReentrantLock lock) {
        Condition condition = lock.newCondition();
        Condition previous = (Condition) this.conditions.putIfAbsent(lock, condition);
        return previous == null ? condition : previous;
    }


以上为大概逻辑,目前是可以处理这种业务场景.

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值