java epoll是什么,讓我們一起了解一下?
epoll是Linux內(nèi)核為處理大批量文件描述符而作了改進(jìn)的poll,是Linux下多路復(fù)用IO接口select或poll的增強(qiáng)版本,能顯著提高程序在大量并發(fā)連接中只有少量活躍的情況下的系統(tǒng)CPU利用率。
如何實(shí)現(xiàn)epoll的接口?
1、創(chuàng)建epoll句柄。
2、將被監(jiān)聽的描述符添加到epoll句柄或從epool句柄中刪除或者對監(jiān)聽事件進(jìn)行修改。
3、等待事件觸發(fā),當(dāng)超過timeout還沒有事件觸發(fā)時,就超時。
在Java中epoll的優(yōu)點(diǎn)有哪些?
1、支持一個進(jìn)程打開大數(shù)目的socket描述符。
2、IO效率不隨FD數(shù)目增加而線性下降。
3、沒有使用mmap加速內(nèi)核與用戶空間的消息傳遞。
如何使用多路復(fù)用的服務(wù)端程序,來演示JavaAPI中提供的方法與底層epoll函數(shù)實(shí)現(xiàn)的具體關(guān)系?
首先程序運(yùn)行后服務(wù)端啟動并綁定9090端口,等待客戶端連接,讀取到客戶端消息后再直接把消息后回復(fù)給客戶端。
示例代碼如下:
import?java.io.IOException; import?java.net.InetSocketAddress; import?java.nio.ByteBuffer; import?java.nio.channels.*; import?java.util.Iterator; import?java.util.Set; public?class?SocketMultiplexIO?{ ????private?static?Selector?selector; ????public?static?void?main(String[]?args)?throws?Exception?{ ????????ServerSocketChannel?serverSocketChannel?=?ServerSocketChannel.open(); ????????serverSocketChannel.bind(new?InetSocketAddress(9090)); ????????serverSocketChannel.configureBlocking(false); ????????selector?=?Selector.open(); ????????serverSocketChannel.register(selector,?SelectionKey.OP_ACCEPT); ????????System.out.println("服務(wù)端啟動了。。。"); ????????while?(true)?{ ????????????Set?keys?=?selector.keys(); ????????????System.out.println("當(dāng)前epoll注冊的事件:"?+?keys.size()); ????????????while?(selector.select()?>?0)?{ ????????????????Set ?selectionKeys?=?selector.selectedKeys(); ????????????????Iterator ?iterator?=?selectionKeys.iterator(); ????????????????while?(iterator.hasNext())?{ ????????????????????SelectionKey?selectionKey?=?iterator.next(); ????????????????????iterator.remove(); ????????????????????if?(selectionKey.isAcceptable())?{ ????????????????????????System.out.println("有一個客戶端連接了。。。"); ????????????????????????acceptHandler(selectionKey); ????????????????????}?else?if?(selectionKey.isReadable())?{ ????????????????????????selectionKey.cancel(); ????????????????????????System.out.println("cancel函數(shù),取消了accept事件"); ????????????????????????readHandler(selectionKey); ????????????????????} ????????????????} ????????????} ????????} ????} ????private?static?void?readHandler(SelectionKey?key)?{ ????????SocketChannel?client?=?(SocketChannel)?key.channel(); ????????ByteBuffer?buffer?=?(ByteBuffer)?key.attachment(); ????????buffer.clear(); ????????int?read; ????????try?{ ????????????while?(true)?{ ????????????????read?=?client.read(buffer); ????????????????if?(read?>?0)?{ ????????????????????buffer.flip(); ????????????????????while?(buffer.hasRemaining())?{ ????????????????????????client.write(buffer); ????????????????????} ????????????????????buffer.clear(); ????????????????}?else?if?(read?==?0)?{ ????????????????????break; ????????????????}?else?{ ????????????????????client.close(); ????????????????????break; ????????????????} ????????????} ????????}?catch?(IOException?e)?{ ????????????e.printStackTrace(); ????????} ????} ????private?static?void?acceptHandler(SelectionKey?selectionKey)?throws?IOException?{ ????????ServerSocketChannel?serverSocketChannel?=?(ServerSocketChannel)?selectionKey.channel(); ????????SocketChannel?accept?=?serverSocketChannel.accept(); ????????accept.configureBlocking(false); ????????ByteBuffer?byteBuffer?=?ByteBuffer.allocateDirect(1024); ????????accept.register(selector,?SelectionKey.OP_READ,?byteBuffer); ????} }
以上就是小編今天的分享了,希望可以幫助到大家。