第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

如何避免事件驅(qū)動(dòng) Java 中繁忙的 while 循環(huán)

如何避免事件驅(qū)動(dòng) Java 中繁忙的 while 循環(huán)

慕仙森 2023-10-12 16:43:30
我目前正在按以下方式開發(fā)事件驅(qū)動(dòng)的 Java 軟件(這是我的主要方法的本質(zhì)):while(true) {    Event event = eventListener.poll();    if(event != null) {        // do something    } else {        // do nothing as usual, but burn CPU time.    }}根據(jù)我正在構(gòu)建的內(nèi)容,eventListener可能會(huì)監(jiān)聽外部 websocket、輪詢 Redis 通道以獲取更新,或者等待來自同一盒子上的另一個(gè)進(jìn)程的消息(可能通過 UDP/TCP/shm)。eventListener我的想法是,這種繁忙的循環(huán)方法在返回 null 時(shí)(大多數(shù)情況下)會(huì)浪費(fèi)大量 CPU 時(shí)間,因?yàn)樗皇亲谀抢镄D(zhuǎn)。但是,除了每次迭代之外,我不知道如何實(shí)現(xiàn)此設(shè)計(jì),Thread.sleep這不是一個(gè)很好的解決方案。理想情況下我想要一個(gè)方法:void run(Event event) {    // do something}run每當(dāng)事件發(fā)生時(shí)都會(huì)調(diào)用where eventListener。如果沒有這樣的事件可用,則理想情況下該過程應(yīng)該只是閑置?,F(xiàn)在,我知道有一些 websocket 庫實(shí)際上可以做到這一點(diǎn),我想知道的是我如何為自己構(gòu)建這樣的東西,并將我的 CPU 從坐在那里浪費(fèi)自己無所事事的狀態(tài)中解放出來?
查看完整描述

2 回答

?
慕姐4208626

TA貢獻(xiàn)1852條經(jīng)驗(yàn) 獲得超7個(gè)贊

您需要使用java非阻塞IO,并且可能是一些支持通過java NIO進(jìn)行高級(jí)通信的庫(例如netty,它支持HTTP、websockets和redis等的NIO風(fēng)格通信)。

以下是 NIO 工作原理的簡(jiǎn)短描述。你正在尋找的東西是Selector.?它允許等待通道(這是文件或網(wǎng)絡(luò)連接等的抽象)上的數(shù)據(jù)可用。此 wait(Selector.select方法) 是阻塞的,當(dāng)某些數(shù)據(jù)可供讀取或要寫入的輸出緩沖區(qū)可以獲得新數(shù)據(jù)時(shí),操作系統(tǒng)會(huì)恢復(fù)該進(jìn)程。

代碼大致如下所示:

Selector selector = createSelector();

Channel channel = createChannelForSocket();


SelectionKey key = channel.register(selector);


while(true) {


? int readyChannels = selector.select(TIMEOUT);


? if(readyChannels == 0) continue;


? Set<SelectionKey> selectedKeys = selector.selectedKeys();


? for(SelectionKey key : selectedKeys) {


? ? if (key.isReadable()) {

? ? ? ? readDataFromChannel(key.channel())

? ? } else if (key.isWritable()) {

? ? ? ? writeDataToChannel(key.channel())

? ? }


? }

}

使用netty,您可以擁有更高級(jí)別的代碼,您可以在其中定義一個(gè)Handlerwhich,它有一個(gè)類似于which的方法void channelRead(ChannelHandlerContext ctx, Object msg),它是一種讀取事件偵聽器,您可以實(shí)現(xiàn)它來偵聽讀取事件。


netty 有一個(gè)內(nèi)置循環(huán),看起來與上面的示例類似,但對(duì)于許多事件偵聽器來說,它將這些事件傳播到特定的偵聽器。


查看完整回答
反對(duì) 回復(fù) 2023-10-12
?
aluckdog

TA貢獻(xiàn)1847條經(jīng)驗(yàn) 獲得超7個(gè)贊

如果您有興趣大規(guī)模使用事件驅(qū)動(dòng)架構(gòu)。您可能想要使用強(qiáng)大的“事件總線”,例如 Apache Kafka 或 AWS SNS+SQS。為了更簡(jiǎn)單,您可以使用 kalium.alkal.io。這將無縫處理 POJO 或 protobuf 對(duì)象的反/序列化。


kalium.on(Event.class, event -> {


   //doSomething with the event

});


查看完整回答
反對(duì) 回復(fù) 2023-10-12
  • 2 回答
  • 0 關(guān)注
  • 142 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)