java epoll是什么,讓我們一起了解一下?
epoll是Linux內核為處理大批量文件描述符而作了改進的poll,是Linux下多路復用IO接口select或poll的增強版本,能顯著提高程序在大量并發連接中只有少量活躍的情況下的系統CPU利用率。
如何實現epoll的接口?
1、創建epoll句柄。
2、將被監聽的描述符添加到epoll句柄或從epool句柄中刪除或者對監聽事件進行修改。
3、等待事件觸發,當超過timeout還沒有事件觸發時,就超時。
在Java中epoll的優點有哪些?
1、支持一個進程打開大數目的socket描述符。
2、IO效率不隨FD數目增加而線性下降。
3、沒有使用mmap加速內核與用戶空間的消息傳遞。
如何使用多路復用的服務端程序,來演示JavaAPI中提供的方法與底層epoll函數實現的具體關系?
首先程序運行后服務端啟動并綁定9090端口,等待客戶端連接,讀取到客戶端消息后再直接把消息后回復給客戶端。
示例代碼如下:
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("服務端啟動了。。。"); ????????while?(true)?{ ????????????Set?keys?=?selector.keys(); ????????????System.out.println("當前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函數,取消了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); ????} }
以上就是小編今天的分享了,希望可以幫助到大家。