? ? ? ? NIO支持非阻塞模式,以網(wǎng)絡(luò)連接和網(wǎng)絡(luò)數(shù)據(jù)傳輸為例。如果使用阻塞模式,ServerSocketChannel在調(diào)用accept等待客戶端建立連接是阻塞的,沒有連接就一直阻塞。從Channel中讀取客戶端傳送的數(shù)據(jù)也是阻塞的,沒有數(shù)據(jù)就一直阻塞。當(dāng)我們開啟非阻塞模式,等待連接建立時(shí)沒有連接就返回null,等到數(shù)據(jù)時(shí)沒有數(shù)據(jù)就返回0。文章來源:http://www.zghlxwxcb.cn/news/detail-858850.html
// 使用 nio 來理解非阻塞模式, 單線程
// 0. ByteBuffer
ByteBuffer buffer = ByteBuffer.allocate(16);
// 1. 創(chuàng)建了服務(wù)器
ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.configureBlocking(false); // 非阻塞模式
// 2. 綁定監(jiān)聽端口
ssc.bind(new InetSocketAddress(8080));
// 3. 連接集合
List<SocketChannel> channels = new ArrayList<>();
while (true) {
// 4. accept 建立與客戶端連接, SocketChannel 用來與客戶端之間通信
SocketChannel sc = ssc.accept(); // 非阻塞,線程還會(huì)繼續(xù)運(yùn)行,如果沒有連接建立,但sc是null
if (sc != null) {
log.debug("connected... {}", sc);
sc.configureBlocking(false); // 非阻塞模式
channels.add(sc);
}
for (SocketChannel channel : channels) {
// 5. 接收客戶端發(fā)送的數(shù)據(jù)
int read = channel.read(buffer);// 非阻塞,線程仍然會(huì)繼續(xù)運(yùn)行,如果沒有讀到數(shù)據(jù),read 返回 0
if (read > 0) {
buffer.flip();
debugRead(buffer);
buffer.clear();
log.debug("after read...{}", channel);
}
}
}
? ? ? ? 以上雖然是非阻塞模式,但是如果一直沒有連接或者數(shù)據(jù)接收,會(huì)導(dǎo)致CPU空轉(zhuǎn),造成資源浪費(fèi)。為此,最佳方式是使用Selector,其支持單線程綁定多個(gè)channel監(jiān)聽對(duì)應(yīng)類型的事件,在防止完全非阻塞模式CPU空轉(zhuǎn)的同時(shí)也避免了傳統(tǒng)的完全阻塞模式下阻塞等待影響其他需要連接或有數(shù)據(jù)接收的channel的正常工作,這也就是NIO Selector的作用,后續(xù)會(huì)詳細(xì)介紹。文章來源地址http://www.zghlxwxcb.cn/news/detail-858850.html
到了這里,關(guān)于NIO之非阻塞模式的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!