创建NIO多人聊天室

限制BIO多人聊天室的性能的主要原因是因为 阻塞IO的存在

,所以使用 非阻塞IO

项目下载地址:https://download.csdn.net/download/weixin_42528855/12540953

 

阻塞io线程的消耗:

当没有客户端到达时,accept()处于阻塞状态,

但是有客户端到达时,会从阻塞状态 变成 执行状态,会得到一个socket。

这时 会将 socket 的 inputstream   和 output stream 转换成两个线程 或 一个读线程 和 一个单线程池(用于写入)

所以 当有 n个客户端连接时,线程数量会大于 2n。

线程的read,write 操作 在大部分情况下都是处于阻塞状态,这时线程什么事情都没有干,仅仅是等待cpu的调度,而cpu每次调度过来时,都会扫描到线程上,发现该线程 没有任何 取消 它等待的 触发机制的存在(此时仍处于阻塞状态)。此时,cpu看似没有任何消耗,但是cpu要消耗 一个线程与线程的切换 和扫描的时间。

 如果A线程有数据达到,此时 ,会从阻塞 转成 运行状态 ,但是我们只有一个cpu调度,

cpu调度之前是在运行另一个线程。

线程 与线程之间的切换消耗 也是很大的。

我们减少线程数量,就减少了线程之间的切换所要消耗的时间,

也减少了cpu扫描线程等待状态的时间,所以大大减少了cpu的消耗。

另外一个层面:减少内存累积:每一个线程创建的时候,必然存在维护这个线程一系列状态的一些参数(比如:维护状态是否运行,一系列IO的调度, 用户态和内核态的连接关系上的一些参数的维持)这些都是属于这个线程的。

 

 

关于NIO Selector的一些知识:(感觉很不错)

https://www.cnblogs.com/snailclimb/p/9086334.html

使用NIO重写服务器:

优化方向:

AccepterThread  :监听新客户端的连接,并且 完成连接。

ProcessorThread:

socketChannel 之后一系列的 IO输入和输出

这些操作 交给一个线程池 ProcessorThread(或线程【不推荐】)去做。

使用线程池 会尽可能 保证 客户端的处理是分离的(并行的),

但是 并不能保证一定是一个并行的过程。比如:

有一个线程池有4个线程,这时有20个客户端连接,并且同时有20个客户端都在发消息,

这时 线程池只能同时处理4个线程,其余的只能等到前面4个完成后,才能进行处理(这也是并行和串行结合的过程)

 注意:IoConntext 的 setUp 方法,被写成静态类且在main函数中启动,所以IoSelectorProvider只被初始化一次。

读和写的selector 都只有一个

目前只是对 服务端中的 ClientHandler 中的数据监听进行了优化,对于转发没有进行改动。

在 TCPServer 中 也是使用一个 线程来监听客户端的到达

ClientListener类: 将得到的 客户端的  socketChannel传给 ClientHandler,

然后 在  ClientHandler 中初始化了 一个 Connector 类【一个对外提供的类,初始化了SocketChannelAdapter 】,

即  ClientHandler 得到的 socketChannel 实际上是传到了 SocketChannelAdapter  中【SocketChannelAdapter 是每次有新客户端过来时,就会重新注册一个】。

在 SocketChannelAdapter  中   有一个 receiveAsync 函数

/**
 *   接收异步:
 *  1.  receiveIoEventListener = listener;   有用吗?
 *  receiveIoEventListener是全局变量,在 SocketChannelAdapter类中的 inputCallback 的创建中使用
 *  2. inputCallback 是在  ioProvider.registerInput 函数中的 注册 成功后 ,存入map中:- map.put(key, inputCallback);
 *  3.如果监听到,则在 handleSelection 中 回调使用
 *
 */

现在来看IoSelectorProvider(对数据读写的具体实现):

 

startRead()  和 startWrite() 是对已经注册过的监听,作用于Server 类的开头

猜你喜欢

转载自blog.csdn.net/weixin_42528855/article/details/106825222
今日推荐