网络服务端几种模式处理模式

1.单线程 bio

    如果单线程普通accept(),则会顺序读取连接socket,如果需要读取socket内容,则inputStream.read()会造成阻塞,这样不但影响了其他socket的读取,也使得tcp连接无法进行复用(因为要顺序处理每一个socket),所以采用了多线程。

2.多线程 bio

    多线程的方式,依然有可能阻塞在 inputStream.read()上,但是不用影响其他线程处理socket的进度,也使得tcp连接可以复用(while true 循环)。缺点是,多线程会有上下文切换,存在一定的开销。其次,依然会有线程被阻塞住,(inputStream.read()),虽然阻塞会挂起线程,但依然浪费了线程的资源。由于一个线程只能处理一个socket,无法应对高并发场景。

3.单线程 nio

    单线程 IO多路复用的方式,这种方式没有做过实验,可以拿redis开刀试试。拿select()举例,这种方式是阻塞在了 select()这个方法上的,当所有的io描述符有可以处理的情况时,使用非阻塞io来进行处理(因为此时一定可以读取正确内容)。相对于多线程的方式,单线程省去了上下文切换的开销,而且阻塞的话,也只会阻塞一个线程,而多线程可能多个线程都处于阻塞(虽然会挂起,>但是挂起之后再唤醒,依然会有资源浪费)。其次,这种方式可以处理多种IO就绪状态,比较灵活。然而,如果每次处理时间较长时,仍然会造成后续排队的请求等待时间较长,所以redis把数据结构精细化,使得最差的操作的复杂度也能为O(n),每次网络请求都很精简,所以能处理高并发的请求。不好的地方是,select() 需要维护所有的注册连接。

总结:至于高并发,bio模型下是无法实现高并发的,因为线程数量有限,每个运行线程对应一个socket。所以只有nio可以实现高并发,比如IO多路复用,或者参考 tomcat 的处理方式。所以 socket 高并发场景 使用 bio是行不通的,因为一个线程对应一个请求,线程数量是有限的。所以只能使用 nio。而nio可以和 selector很好的结合使用,selector 可以使用单线程来实现。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容