服务器模型——从单线程阻塞到多线程非阻塞(中)

前言的前言

服务器模型涉及到线程模式和IO模式,搞清楚这些就能针对各种场景有的放矢。该系列分成三部分:
* 单线程/多线程阻塞I/O模型
* 单线程非阻塞I/O模型
* 多线程非阻塞I/O模型,Reactor及其改进

前言

这里探讨的服务器模型主要指的是服务器端对I/O的处理模型。从不同维度可以有不同的分类,这里从I/O的阻塞与非阻塞、I/O处理的单线程与多线程角度探讨服务器模型。

对于I/O,可以分成阻塞I/O与非阻塞I/O两大类型。阻塞I/O在做I/O读写操作时会使当前线程进入阻塞状态,而非阻塞I/O则不进入阻塞状态。

对于线程,单线程情况下由一条线程负责所有客户端连接的I/O操作,而多线程情况下则由若干线程共同处理所有客户端连接的I/O操作。

单线程非阻塞I/O模型

多线程阻塞I/O模型通过引入多线程确实提高了服务器端的并发处理能力,但每个连接都需要一个线程负责I/O操作。当连接数量较多时可能导致机器线程数量太多,而这些线程大多数时间却处于等待状态,造成极大的资源浪费。鉴于多线程阻塞I/O模型的缺点,有没有可能用一个线程就可以维护多个客户端连接并且不会阻塞在读写操作呢?下面介绍单线程非阻塞I/O模型。

单线程非阻塞I/O模型最重要的一个特点是,在调用读取或写入接口后立即返回,而不会进入阻塞状态。在探讨单线程非阻塞I/O模型前必须要先了解非阻塞情况下套接字事件的检测机制,因为对于单线程非阻塞模型最重要的事情是检测哪些连接有感兴趣的事件发生。一般会有如下三种检测方式。

应用程序遍历套接字的事件检测

当多个客户端向服务器请求时,服务器端会保存一个套接字连接列表中,应用层线程对套接字列表轮询尝试读取或写入。对于读取操作,如果成功读取到若干数据,则对读取到的数据进行处理;如果读取失败,则下一个循环再继续尝试。对于写入操作,先尝试将数据写入指定的某个套接字,写入失败则下一个循环再继续尝试。

你可能感兴趣的:(Java并发)