摘要:關于多路復用很多人用過和接口,用來操作文件等等操作。熟悉操作系統的人會知道,操作非阻塞無非幾種多路復用這里的復用模型有幾個是操作系統相關的也就是說,并不是所有的操作系統都可以用,典型的就是是的專利,是的專利比如。
關于多路復用
很多人用過InputStream和OutputStream接口,用來操作文件、Socket等等 IO 操作。
如果是簡單的,速度較快的 IO 操作,我們用Stream類的接口,依然可以風生水起。
如果你要使用非阻塞的 IO 的話,他們可能就滿足不了你了。
熟悉操作系統的人會知道,操作非阻塞 IO 無非幾種多路復用:
select
poll
epoll
kqueue
IOCP
這里的復用模型有幾個是操作系統相關的——也就是說,并不是所有的操作系統都可以用,典型的就是IOCP是Windows的"專利",kqueue是BSD的"專利"(比如macOS)。
那么 java 作為一門跨平臺的語言解決方案,是如何在虛擬機上使用 non-blocking IO 的呢?
具體的實現我們可以不管,它使用了Selector的 API,調用方式非常類似select。
在nio中,不再使用Stream API對Socket進行交互,而是使用Channel和ByteBuffer進行交互,
Channel負責管道的工作,ByteBuffer負責緩存的工作。
原先InputStream和OutputStream的工作就由Channel做掉了,如果這個Channel支持Select模型的話,它就是SelectableChannel的子類。
那么,在消息循環的模型中,首先要建立循環,像我們的Looper.loop()一樣,我們先用Selector.open()新建一個Selector
Selector eventSelector = Selector.open(); // 設置這個 channel 是非阻塞的 socketChannel.configureBlocking(false); // 注冊到 selector 里,并設置好關心的事件 socketSelectionKey = socketChannel.register(eventSelector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);Selector
接下來調用 eventSelector.select() 阻塞,就能在你關心的事件到來的時候,阻塞就會被喚醒,處理事件。
sample:
while (connected) { eventSelector.select(); Set總結keys = eventSelector.selectedKeys(); Iterator iterator = keys.iterator(); while (iterator.hasNext()) { SelectionKey key = iterator.next(); if (key.isReadable()) { // 當 socket 可讀 internalOnRead((ReadableByteChannel) key.channel()); } if (key.isWritable()) { // 當 socket 可寫 internalOnWrite((WritableByteChannel) key.channel()); } iterator.remove(); } }
nio 對于客戶端的優勢幾乎沒有,但是可以讓代碼更好管理; 如果這時候你使用的是ServerSocket,好處就立馬體現了,因為你的業務需求很可能是這樣:
master 線程,開啟 accept.
如果有客戶接入,開啟一個 worker,用來服務 client。
服務完后,保持或者關閉這個連接。
(這個業務模型類似Apache httpd)這樣的業務模型可能導致過多的線程開銷,使得并發量并不高。
那么,老生常談的event-driven的模型在java中,就差不多是這樣的邏輯:
master 線程,開啟 selector, 并為 ServerSocket 注冊 accept, read, write 等事件。
客戶接入,為 client socket 注冊 read, write 事件,依舊在該線程里面進行循環。
當 event trigger 的時候,處理相關業務邏輯。
第二個模型只啟動了一個線程,所有的IO操作都在 OS 里面完成了,用戶空間內的資源消耗大大降低,這也是我們把 Server 端的 IO 改成 nio 的優勢。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/66687.html
摘要:的選擇器允許單個線程監視多個輸入通道。一旦執行的線程已經超過讀取代碼中的某個數據片段,該線程就不會在數據中向后移動通常不會。 1、引言 很多初涉網絡編程的程序員,在研究Java NIO(即異步IO)和經典IO(也就是常說的阻塞式IO)的API時,很快就會發現一個問題:我什么時候應該使用經典IO,什么時候應該使用NIO? 在本文中,將嘗試用簡明扼要的文字,闡明Java NIO和經典IO之...
時間:2018年04月11日星期三 說明:本文部分內容均來自慕課網。@慕課網:https://www.imooc.com 教學源碼:https://github.com/zccodere/s... 學習源碼:https://github.com/zccodere/s... 第一章:課程介紹 1-1 課程介紹 什么是Netty 高性能、事件驅動、異步非阻塞的IO Java開源框架 基于NIO的客戶...
摘要:好了,目前還不難,我們起碼知道這個抽象類上面的部分關系,因此當然也有自己的方法,如下。又來一個的供應商好吧,大佬們總是喜歡用一些設計模式的東西,沒錯,也是一個抽象類,這個現在不用太在意了。 前言 java nio,一個入門netty之前需要了解下的非阻塞I/O實現,傳統的Socket通信,啟動監聽后accept會一直處于阻塞狀態,那么如果你想要多個(并發)通信時,那么我們就需要多個線性...
摘要:表示的是兩個,當其中任意一個計算完并發編程之是線程安全并且高效的,在并發編程中經常可見它的使用,在開始分析它的高并發實現機制前,先講講廢話,看看它是如何被引入的。電商秒殺和搶購,是兩個比較典型的互聯網高并發場景。 干貨:深度剖析分布式搜索引擎設計 分布式,高可用,和機器學習一樣,最近幾年被提及得最多的名詞,聽名字多牛逼,來,我們一步一步來擊破前兩個名詞,今天我們首先來說說分布式。 探究...
閱讀 1483·2023-04-25 15:40
閱讀 2834·2021-08-11 11:15
閱讀 2273·2019-08-26 13:48
閱讀 2844·2019-08-26 12:18
閱讀 2448·2019-08-23 18:23
閱讀 2905·2019-08-23 17:01
閱讀 2978·2019-08-23 16:29
閱讀 1101·2019-08-23 15:15