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

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

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

服務(wù)器之家 - 編程語言 - Java教程 - 詳解Java中CountDownLatch異步轉(zhuǎn)同步工具類

詳解Java中CountDownLatch異步轉(zhuǎn)同步工具類

2021-09-22 00:57lingzhi_ying Java教程

今天給大家?guī)淼氖顷P(guān)于Java的相關(guān)知識,文章圍繞著CountDownLatch異步轉(zhuǎn)同步工具類展開,文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下

使用場景

由于公司業(yè)務(wù)需求,需要對接socket、MQTT等消息隊(duì)列。
眾所周知 socket 是雙向通信,socket的回復(fù)是人為定義的,客戶端推送消息給服務(wù)端,服務(wù)端的回復(fù)是兩條線。無法像http請求有回復(fù)。
下發(fā)指令給硬件時(shí),需要校驗(yàn)此次數(shù)據(jù)下發(fā)是否成功。
用戶體驗(yàn)而言,點(diǎn)擊按鈕就要知道此次的下發(fā)成功或失敗。

詳解Java中CountDownLatch異步轉(zhuǎn)同步工具類

如上圖模型,

第一種方案使用Tread.sleep
優(yōu)點(diǎn):占用資源小,放棄當(dāng)前cpu資源
缺點(diǎn): 回復(fù)速度快,休眠時(shí)間過長,仍然需要等待休眠結(jié)束才能返回,響應(yīng)速度是固定的,無法及時(shí)響應(yīng)第二種方案使用CountDownLatch

?
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package com.lzy.demo.delay;
 
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
 
public class CountDownLatchPool {
 
    //countDonw池
    private final static Map<Integer, CountDownLatch> countDownLatchMap = new ConcurrentHashMap<>();
    //延遲隊(duì)列
    private final static DelayQueue<MessageDelayQueueUtil> delayQueue = new DelayQueue<>();
 
    private volatile static boolean flag =false;
    //單線程池
    private final static ExecutorService t = new ThreadPoolExecutor(1, 1,
        0L, TimeUnit.MILLISECONDS,
        new ArrayBlockingQueue<>(1));
 
    public static void addCountDownLatch(Integer messageId) {
        CountDownLatch countDownLatch = countDownLatchMap.putIfAbsent(messageId,new CountDownLatch(1) );
        if(countDownLatch == null){
            countDownLatch = countDownLatchMap.get(messageId);
        }
        try {
            addDelayQueue(messageId);
            countDownLatch.await(3L, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("阻塞等待結(jié)束~~~~~~");
    }
 
    public static void removeCountDownLatch(Integer messageId){
        CountDownLatch countDownLatch = countDownLatchMap.get(messageId);
        if(countDownLatch == null)
            return;
        countDownLatch.countDown();
        countDownLatchMap.remove(messageId);
        System.out.println("清除Map數(shù)據(jù)"+countDownLatchMap);
    }
 
    private static void addDelayQueue(Integer messageId){
        delayQueue.add(new MessageDelayQueueUtil(messageId));
        clearMessageId();
    }
 
    private static void clearMessageId(){
        synchronized (CountDownLatchPool.class){
            if(flag){
                return;
            }
            flag = true;
        }
        t.execute(()->{
            while (delayQueue.size() > 0){
                System.out.println("進(jìn)入線程并開始執(zhí)行");
                try {
                    MessageDelayQueueUtil take = delayQueue.take();
                    Integer messageId1 = take.getMessageId();
                    removeCountDownLatch(messageId1);
                    System.out.println("清除隊(duì)列數(shù)據(jù)"+messageId1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            flag = false;
            System.out.println("結(jié)束end----");
        });
    }
 
    public static void main(String[] args) throws InterruptedException {
        /*
        測試超時(shí)清空map
        new Thread(()->addCountDownLatch(1)).start();
        new Thread(()->addCountDownLatch(2)).start();
        new Thread(()->addCountDownLatch(3)).start();
        */
        //提前創(chuàng)建線程,清空countdown
        new Thread(()->{
            try {
                Thread.sleep(500L);
                removeCountDownLatch(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
        //開始阻塞
        addCountDownLatch(1);
        //通過調(diào)整上面的sleep我們發(fā)現(xiàn)阻塞市場取決于countDownLatch.countDown()執(zhí)行時(shí)間
        System.out.println("阻塞結(jié)束----");
    }
}
class MessageDelayQueueUtil implements Delayed {
 
    private Integer messageId;
    private long avaibleTime;
 
    public Integer getMessageId() {
        return messageId;
    }
 
    public void setMessageId(Integer messageId) {
        this.messageId = messageId;
    }
 
    public long getAvaibleTime() {
        return avaibleTime;
    }
 
    public void setAvaibleTime(long avaibleTime) {
        this.avaibleTime = avaibleTime;
    }
 
    public MessageDelayQueueUtil(Integer messageId){
        this.messageId = messageId;
        //avaibleTime = 當(dāng)前時(shí)間+ delayTime
        //重試3次,每次3秒+1秒的延遲
        this.avaibleTime=3000*3+1000 + System.currentTimeMillis();
    }
 
    @Override
    public long getDelay(TimeUnit unit) {
        long diffTime= avaibleTime- System.currentTimeMillis();
        return unit.convert(diffTime,TimeUnit.MILLISECONDS);
    }
 
    @Override
    public int compareTo(Delayed o) {
        //compareTo用在DelayedUser的排序
        return (int)(this.avaibleTime - ((MessageDelayQueueUtil) o).getAvaibleTime());
    }
}

由于socket并不確定每次都會有數(shù)據(jù)返回,所以map的數(shù)據(jù)會越來越大,最終導(dǎo)致內(nèi)存溢出
需定時(shí)清除map內(nèi)的無效數(shù)據(jù)。
可以使用DelayedQuene延遲隊(duì)列來處理,相當(dāng)于給對象添加一個(gè)過期時(shí)間

使用方法 addCountDownLatch 等待消息,異步回調(diào)消息清空removeCountDownLatch

到此這篇關(guān)于詳解Java中CountDownLatch異步轉(zhuǎn)同步工具類的文章就介紹到這了,更多相關(guān)CountDownLatch異步轉(zhuǎn)同步工具類內(nèi)容請搜索服務(wù)器之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持服務(wù)器之家!

原文鏈接:https://blog.csdn.net/qq_37256345/article/details/117808156

延伸 · 閱讀

精彩推薦
  • Java教程20個(gè)非常實(shí)用的Java程序代碼片段

    20個(gè)非常實(shí)用的Java程序代碼片段

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

    lijiao5352020-04-06
  • Java教程Java8中Stream使用的一個(gè)注意事項(xiàng)

    Java8中Stream使用的一個(gè)注意事項(xiàng)

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

    阿杜7472021-02-04
  • Java教程Java BufferWriter寫文件寫不進(jìn)去或缺失數(shù)據(jù)的解決

    Java BufferWriter寫文件寫不進(jìn)去或缺失數(shù)據(jù)的解決

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

    spcoder14552021-10-18
  • Java教程升級IDEA后Lombok不能使用的解決方法

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

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

    程序猿DD9332021-10-08
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

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

    大行者10067412021-08-30
  • Java教程Java實(shí)現(xiàn)搶紅包功能

    Java實(shí)現(xiàn)搶紅包功能

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

    littleschemer13532021-05-16
  • Java教程xml與Java對象的轉(zhuǎn)換詳解

    xml與Java對象的轉(zhuǎn)換詳解

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

    Java教程網(wǎng)2942020-09-17
  • Java教程小米推送Java代碼

    小米推送Java代碼

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

    富貴穩(wěn)中求8032021-07-12
主站蜘蛛池模板: heyzo1754北岛玲在线视频 | 小妇人电影免费完整观看2021 | 性夜影院午夜看片 | 91在线视频免费观看 | 特黄级 | 国产精品青青在线观看香蕉 | 毛片资源 | 亚洲无毛片 | 国产成人精品777 | 村妇超级乱淫伦小说全集 | 亚州精品永久观看视频 | 9191久久| 俄罗斯激情性孕妇孕交大全 | 天堂俺去俺来也www久久婷婷 | 性xxxx中国| 欧美三级不卡在线观线看高清 | 好男人社区www影院在线观看 | 四虎在线成人免费网站 | 黄 在线播放 | 四虎黄色影视库 | 青青青国产精品国产精品久久久久 | 国产亚洲自愉自愉 | 日韩在线免费播放 | 成人区精品一区二区毛片不卡 | 婷婷99视频精品全部在线观看 | 四虎影院在线免费观看视频 | 亚洲zooz人禽交xxxx | 精品一区二区三区波多野结衣 | 给我免费观看的视频在线播放 | 国产精品久久久久久影视 | tiny4k欧美极品在线 | 动漫美丽妇人1~2在线看 | 欧美精品国产一区二区 | tolove第一季动画在线看 | 国产精品成人麻豆专区 | 好逼天天有 | a及毛片| 草久热 | 成年极品漫画在线观看 | 国产玖玖在线观看 | 欧美一级欧美三级 |