欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java如何使用ReentrantLock實(shí)現(xiàn)長(zhǎng)輪詢

 更新時(shí)間:2021年04月08日 17:16:08   作者:NichenFly  
這篇文章主要介紹了如何使用ReentrantLock實(shí)現(xiàn)長(zhǎng)輪詢,對(duì)ReentrantLock感興趣的同學(xué),可以參考下

Java代碼

1. ReentrantLock

加鎖阻塞,一個(gè)condition對(duì)應(yīng)一個(gè)線程,以便于喚醒時(shí)使用該condition一定會(huì)喚醒該線程

/**
     * 獲取探測(cè)點(diǎn)數(shù)據(jù),長(zhǎng)輪詢實(shí)現(xiàn)
     * @param messageId
     * @return
     */
    public JSONObject getToutData(String messageId) {
        Message message = toutMessageCache.get(messageId);
        if (message == null) {
            // 等待
            lock.lock();
            try {
                Condition condition = lock.newCondition();
                conditionMap.put(messageId + "_data", condition);
                condition.await(CONNECTION_HOLD_TIMEOUT, TimeUnit.SECONDS); // 等待60s
            } catch (InterruptedException e) {
                // 等待超時(shí), do nothing
            } finally {
                lock.unlock();
            }
        }

        // 再次嘗試獲取
        message = toutMessageCache.get(messageId);
        if (message == null) {
            // 如果還沒(méi)有, 返回空對(duì)象
            return null;
        }

        byte[] bytes = message.getDataBytes();
        if (bytes == null) {
            return null;
        }
        String resStr = new String(bytes, StandardCharsets.UTF_8);
//        log.info("resStr: {}", resStr);
        JSONObject resObj;
        try {
            resObj = new JSONObject(resStr);
            resObj.put("invokeTime", DateUtil.format(new Date(resObj.getLong("invokeTime")), DatePattern.NORM_DATETIME_MS_PATTERN));
        } catch (Exception e) {
            resObj = new JSONObject();
        }

        return resObj;
    }

2. 回調(diào)

當(dāng)異步數(shù)據(jù)返回,使用上一步的condition喚醒線程

public void callback(Message message) {
    String messageId = message.getId();
    toutMessageCache.put(message.getId(), message);
    String messageDataId = messageId + "_data";
    if (conditionMap.containsKey(messageDataId)) {
        lock.lock();
        try {
            Condition condition = conditionMap.get(messageDataId);
            condition.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
            conditionMap.remove(messageDataId);
        }
    }
}

3. 喚醒

執(zhí)行回調(diào)操作

public void distribute(Message message, ChannelHandlerContext ctx) {
   MessageType messageType = message.getMessageType();
   switch (messageType) {
       case TOUT_DATA_RESPONSE:
           // 數(shù)據(jù)響應(yīng)
           toutService.callback(message);
           break;
   }

}

4. 調(diào)用

調(diào)用時(shí),判斷返回的值是否為空,如果為空,與前端約定,當(dāng)返回該狀態(tài)值時(shí),應(yīng)再次發(fā)起相同請(qǐng)求

/**
* 獲取探測(cè)數(shù)據(jù)(使用長(zhǎng)輪詢實(shí)現(xiàn))
* @param linkId
* @return
*/
@GetMapping("/data")
public ResultVO getToutData(String linkId) {
   JSONObject resObj = toutService.getToutData(linkId);
   if (resObj == null || resObj.isEmpty()) {
       return ResultVOUtil.error(ResultEnum.NO_MESSAGE_HOLD_CONNECTION);
   }
   return ResultVOUtil.success(resObj);
}

5.前端實(shí)現(xiàn)

簡(jiǎn)單使用遞歸實(shí)現(xiàn)了當(dāng)數(shù)據(jù)返回?zé)o效時(shí)再次發(fā)起請(qǐng)求

let that = this
function getData() {
     if (toutStatus === statusEnum.start) {
         getToutData({
             linkId
         }).then(res => {
             if (res.code === ERROR_CODE_OK) {
                 that.toutData = res.data
                 toutStatus = statusEnum.resData
                 that._btnStatus()
             } else {
                 getData()
             }
         })
     }
 }

 // 遞歸循環(huán)調(diào)用
 getData()

以上就是如何使用ReentrantLock實(shí)現(xiàn)長(zhǎng)輪詢的詳細(xì)內(nèi)容,更多關(guān)于ReentrantLock長(zhǎng)輪詢的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • IDEA 當(dāng)前在線人數(shù)和歷史訪問(wèn)量的示例代碼

    IDEA 當(dāng)前在線人數(shù)和歷史訪問(wèn)量的示例代碼

    這篇文章主要介紹了IDEA 當(dāng)前在線人數(shù)和歷史訪問(wèn)量的實(shí)例代碼,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-08-08
  • 微信支付java版本之JSAPI支付+發(fā)送模板消息

    微信支付java版本之JSAPI支付+發(fā)送模板消息

    這篇文章主要介紹了微信支付java版本之JSAPI支付,發(fā)送模板消息,感興趣的小伙伴們可以參考一下
    2016-08-08
  • SpringBoot實(shí)現(xiàn)給屬性賦值的兩種方式

    SpringBoot實(shí)現(xiàn)給屬性賦值的兩種方式

    在Spring Boot中,配置文件是用來(lái)設(shè)置應(yīng)用程序的各種參數(shù)和操作模式的重要部分,Spring Boot支持兩種主要類型的配置文件:properties文件和YAML 文件,這兩種文件都可以用來(lái)定義相同的配置,接下來(lái)由小編給大家詳細(xì)的介紹一下這兩種方式
    2024-07-07
  • springboot集成mybatis-maven插件自動(dòng)生成pojo的詳細(xì)教程

    springboot集成mybatis-maven插件自動(dòng)生成pojo的詳細(xì)教程

    這篇文章主要介紹了springboot集成mybatis-maven插件自動(dòng)生成pojo的詳細(xì)教程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-01-01
  • java計(jì)算任意位水仙花數(shù)示例(回文數(shù))

    java計(jì)算任意位水仙花數(shù)示例(回文數(shù))

    這篇文章主要介紹了java計(jì)算任意位水仙花數(shù)示例(回文數(shù)),需要的朋友可以參考下
    2014-05-05
  • hibernate 三種狀態(tài)的轉(zhuǎn)換

    hibernate 三種狀態(tài)的轉(zhuǎn)換

    本文主要介紹了hibernate三種狀態(tài)的轉(zhuǎn)換。具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧
    2017-03-03
  • eclipse如何搭建Springboot項(xiàng)目詳解

    eclipse如何搭建Springboot項(xiàng)目詳解

    今天帶大家學(xué)習(xí)eclipse如何搭建Spring boot項(xiàng)目,文中有非常詳細(xì)的圖文解說(shuō),對(duì)正在學(xué)習(xí)java的小伙伴們有很好地幫助,需要的朋友可以參考下
    2021-05-05
  • Java設(shè)計(jì)模式之訪問(wèn)者模式使用場(chǎng)景及代碼示例

    Java設(shè)計(jì)模式之訪問(wèn)者模式使用場(chǎng)景及代碼示例

    這篇文章主要介紹了Java設(shè)計(jì)模式之訪問(wèn)者模式使用場(chǎng)景及代碼示例,小編覺(jué)得還是挺不錯(cuò)的,這里分享給大家,供需要的朋友參考。
    2017-11-11
  • SpringBoot配置多數(shù)據(jù)源的四種方式分享

    SpringBoot配置多數(shù)據(jù)源的四種方式分享

    在日常開(kāi)發(fā)中我們都是以單個(gè)數(shù)據(jù)庫(kù)進(jìn)行開(kāi)發(fā),在小型項(xiàng)目中是完全能夠滿足需求的,但是,當(dāng)我們牽扯到大型項(xiàng)目的時(shí)候,單個(gè)數(shù)據(jù)庫(kù)就難以承受用戶的CRUD操作,那么此時(shí),我們就需要使用多個(gè)數(shù)據(jù)源進(jìn)行讀寫(xiě)分離的操作,本文就給大家介紹SpringBoot配置多數(shù)據(jù)源的方式
    2023-07-07
  • 基于Java ORM框架的使用詳解

    基于Java ORM框架的使用詳解

    本篇文章是對(duì)Java中ORM框架的使用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05

最新評(píng)論