一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java如何使用ReentrantLock實現長輪詢

Java如何使用ReentrantLock實現長輪詢

2021-09-03 11:44NichenFly Java教程

這篇文章主要介紹了如何使用ReentrantLock實現長輪詢,對ReentrantLock感興趣的同學,可以參考下

Java代碼

1. ReentrantLock

加鎖阻塞,一個condition對應一個線程,以便于喚醒時使用該condition一定會喚醒該線程

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/**
     * 獲取探測點數據,長輪詢實現
     * @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) {
                // 等待超時, do nothing
            } finally {
                lock.unlock();
            }
        }
 
        // 再次嘗試獲取
        message = toutMessageCache.get(messageId);
        if (message == null) {
            // 如果還沒有, 返回空對象
            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. 回調

當異步數據返回,使用上一步的condition喚醒線程

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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. 喚醒

執行回調操作

?
1
2
3
4
5
6
7
8
9
10
public void distribute(Message message, ChannelHandlerContext ctx) {
   MessageType messageType = message.getMessageType();
   switch (messageType) {
       case TOUT_DATA_RESPONSE:
           // 數據響應
           toutService.callback(message);
           break;
   }
 
}

4. 調用

調用時,判斷返回的值是否為空,如果為空,與前端約定,當返回該狀態值時,應再次發起相同請求

?
1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* 獲取探測數據(使用長輪詢實現)
* @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.前端實現

簡單使用遞歸實現了當數據返回無效時再次發起請求

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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()
             }
         })
     }
 }
 
 // 遞歸循環調用
 getData()

以上就是如何使用ReentrantLock實現長輪詢的詳細內容,更多關于ReentrantLock長輪詢的資料請關注服務器之家其它相關文章!

原文鏈接:https://blog.csdn.net/weixin_42096329/article/details/115470071

延伸 · 閱讀

精彩推薦
  • Java教程小米推送Java代碼

    小米推送Java代碼

    今天小編就為大家分享一篇關于小米推送Java代碼,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧...

    富貴穩中求8032021-07-12
  • Java教程升級IDEA后Lombok不能使用的解決方法

    升級IDEA后Lombok不能使用的解決方法

    最近看到提示IDEA提示升級,尋思已經有好久沒有升過級了。升級完畢重啟之后,突然發現好多錯誤,本文就來介紹一下如何解決,感興趣的可以了解一下...

    程序猿DD9332021-10-08
  • Java教程Java BufferWriter寫文件寫不進去或缺失數據的解決

    Java BufferWriter寫文件寫不進去或缺失數據的解決

    這篇文章主要介紹了Java BufferWriter寫文件寫不進去或缺失數據的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望...

    spcoder14552021-10-18
  • Java教程20個非常實用的Java程序代碼片段

    20個非常實用的Java程序代碼片段

    這篇文章主要為大家分享了20個非常實用的Java程序片段,對java開發項目有所幫助,感興趣的小伙伴們可以參考一下 ...

    lijiao5352020-04-06
  • Java教程Java8中Stream使用的一個注意事項

    Java8中Stream使用的一個注意事項

    最近在工作中發現了對于集合操作轉換的神器,java8新特性 stream,但在使用中遇到了一個非常重要的注意點,所以這篇文章主要給大家介紹了關于Java8中S...

    阿杜7472021-02-04
  • Java教程xml與Java對象的轉換詳解

    xml與Java對象的轉換詳解

    這篇文章主要介紹了xml與Java對象的轉換詳解的相關資料,需要的朋友可以參考下...

    Java教程網2942020-09-17
  • Java教程Java實現搶紅包功能

    Java實現搶紅包功能

    這篇文章主要為大家詳細介紹了Java實現搶紅包功能,采用多線程模擬多人同時搶紅包,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙...

    littleschemer13532021-05-16
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

    這篇文章主要介紹了Java使用SAX解析xml的示例,幫助大家更好的理解和學習使用Java,感興趣的朋友可以了解下...

    大行者10067412021-08-30
主站蜘蛛池模板: 美女脱了内裤打开腿让你桶爽 | 精品一区二区三区波多野结衣 | 麻豆性视频| 18xxxx中国| 欧美最猛性xxxxx69交 | 日本国产高清色www视频在线 | 日本免费在线播放 | 饭冈加奈子在线播放观看 | 成人猫咪maomiav永久网址 | 亚洲成人三级 | 日韩去日本高清在线 | 亚洲精品在线播放 | 日本福利视频网站 | 亚洲 欧美 国产 综合首页 | 青青草成人影院 | 亚洲haose在线观看 | 欧美另类亚洲 | 亚洲欧美视频在线播放 | 美女胸又大又黄又www小说 | 色欲麻将 | 97se亚洲国产综合自在线观看 | 四虎影视免费观看免费观看 | 黑白配高清hd在线视频 | 久久婷婷电影网 | dyav午夜片 | 沟厕okn系列在线播放 | 美女脱一净二净不带胸罩 | 99热在线精品播放 | 亚洲无线一二三区2021 | 小小水蜜桃免费影院 | 精品久久国产 | 欧洲vodafone精品性 | 乳色吐息讲的是什么 | 2022最新国产在线 | 无限好资源免费观看 | xxxxx大片在线观看 | 国产欧美一区二区三区久久 | 超级乱淫变态伦短篇小说全集 | 亚洲精品国偷拍自产在线观看蜜臀 | 日本免费一二区 | 精品无码久久久久久久动漫 |