NIO线程模型

2019-06-20  本文已影响0人  我是一名搬运工

1、线程模型

I/O多路复用模型(事件级中间件select):上面的I/O复用模型是启动一个单线程select来监听所有的socket请求,虽然只用一个线程就处理了所有的socket连接,但是不能改变好多socket连接并发的效率问题。I/O多路复用模型则是使用事件驱动的办法,让用户线程在select上注册一类XX事件,然后就不管了。Select在监听内核的过程中,一旦发现XX事件发生了,立马通过用户线程,看用户线程需不需要处理。

2、实现机制


NIO所有client和server都通过channel注册到selector,由selector统一进行调度。Selector监控Thread Pool中的线程资源,一旦有空余线程,并且client或者server已经注册了这类线程的事件,那么Selector从线程池中获取该线程,处理client的IO操作。所有Channel操作的数据统一放到Buffer当中。

3、Socket编程

Server端:

1)通过Selector.open()打开Selector,并且申明一个ServerSocketChannel,注册selector中的ACCEPT事件,表示当前处于可接收Socket连接的状态。

2)不断循环获取Selector中的selectionKeys,一旦有新的socket事件过来,selectionKeys就有新的值,可以获取selectionKey进行处理,selectionKey里面封装了SocketChannel及当前状态。

3)根据selectionKey当前状态的不同,分别处理,对于可接收状态,通过ServerSocketChannel.accept()获取客户端channel,并把客户端channel注册到Selector中的READ事件;对于可读取状态,通过SocketChannel获取到里面的信息,并放到ByteBuffer里面,进行处理。

Client端:

1)通过Selector.open()打开Selector,并且申明一个SocketChannel,连接到Server端的Ip和端口,并注册selector中的CONNECT事件,表示当前处于可连接的状态。

2)不断循环获取Selector中的selectionKeys,一旦有新的socket事件过来,selectionKeys就有新的值,可以获取selectionKey进行处理,selectionKey里面封装了SocketChannel及当前状态。

3)根据selectionKey当前状态的不同,分别处理,对于连接状态,通过SocketChannel.write()向服务端发送消息;对于可读取状态,通过SocketChannel获取到里面的信息,并放到ByteBuffer里面,进行处理。

两端通信:

1)Selector负责监听所有channel的事件状态,负责线程的调度

2)所有channel在Seletor注册不同的事件,通过ByteBuffer读写数据。

上一篇 下一篇

猜你喜欢

热点阅读