java socket nio 阻塞_Java NIO实现非阻塞式socket通信
博主知識(shí)水平有限,只能提供一個(gè)個(gè)人的狹隘的理解,如果有新人讀到這兒,建議看一下其他教程或者API,如果不明白,再來看一下;如果有dalao讀到這兒,希望能指出理解中的問題~謝謝
Java提供了用于網(wǎng)絡(luò)通信的socket和serversocket包,然而實(shí)現(xiàn)方式是阻塞式的,同一時(shí)間點(diǎn)上只能進(jìn)行一個(gè)連接,這會(huì)帶來不好的體驗(yàn)。當(dāng)然了,我們也可以通過不斷創(chuàng)建線程的方式管理連接,但線程多了的話反而會(huì)降低效率。于是Java推出了非阻塞式IO——channel。并且channel提供關(guān)于網(wǎng)絡(luò)通信的相關(guān)channel。
channel將傳統(tǒng)的輸入輸出流合并了,即一個(gè)channel既可以輸入內(nèi)容,也可以輸出內(nèi)容。
并且,使用channel的同時(shí),要用NIO提供的buffer作為中介。
channel類型:
FileChannel
DatagramChannel
SocketChannel
ServerSocketChannel
buffer類型:
ByteBuffer
CharBuffer
DoubleBuffer
FloatBuffer
IntBuffer
LongBuffer
ShortBuffer
為了使用socketchannel與serversocketchannel,請(qǐng)使用工廠模式創(chuàng)建byteBuffer:
ByteBuffer byteBuffer = ByteBuffer.allocate(12);
創(chuàng)建Channel方法:
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
下條語句將指定channel設(shè)為非阻塞式:
serverSocketChannel.configureBlocking(false);
與某端口綁定:
serverSocketChannel.bind(new InetSocketAddress(PORT));
相應(yīng)的如果是socketChannel,方法是connect,這里僅拿ServerSocketChannel舉例。
到此為止,我們還沒有看到channel是如何實(shí)現(xiàn)非阻塞式IO的,于是NIO提供了一種工具——Selector。
Selector,簡單來說,是對(duì)多個(gè)channel的管理工具,我們可以把多個(gè)channel一股腦加進(jìn)去,如果哪個(gè)channel準(zhǔn)備好讀或者寫(或者其他操作)就會(huì)通知我們。
Selector中有一個(gè)interest的概念,意思是在我們把某個(gè)通道注冊(cè)給selector時(shí),我們指明selector要監(jiān)視channel的哪一種行為,畢竟,一種channel可以read,write,accept,connect。
Selector實(shí)例化:
Selector selector = Selector.open();
channel注冊(cè)
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
第二個(gè)參數(shù)為interest類型
interest類型:
SelectionKey.OP_CONNECT
SelectionKey.OP_ACCEPT
SelectionKey.OP_READ
SelectionKey.OP_WRITE
一般的我們給serverSocketChannel注冊(cè)一個(gè)accept就好。
然后,當(dāng)我們調(diào)用selector.select()時(shí),selector會(huì)等待已經(jīng)注冊(cè)的channel,直到有一個(gè)channel準(zhǔn)備好。這個(gè)過程是阻塞式的,當(dāng)然了阻塞又有什么關(guān)系呢,其實(shí)IO還是非阻塞式的。
之后我們引用selector.selectedKeys()會(huì)返回一個(gè)集合,包含了可以響應(yīng)的channel,迭代集合,我們得到一個(gè)個(gè)channel。
噢,其實(shí)并不是得到channel,而是另一種東西——SelectionKey。
SelectionKey包含了挺多信息的,你可以得到他的selector,channel還有注冊(cè)時(shí)的信息。
我們可以通過selectionKey.isReadable,isAcceptable,isConnectable,isWritable獲得我們注冊(cè)時(shí)的信息,然后具體的對(duì)每種響應(yīng)類型處理。
還有,記得迭代完要把對(duì)象remove掉。
總結(jié)
以上是生活随笔為你收集整理的java socket nio 阻塞_Java NIO实现非阻塞式socket通信的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java环形数组_Java数组模拟环形队
- 下一篇: java static变量销毁_JAVA