首页 > 编程知识 正文

java程序设计实用教程,java程序模板

时间:2023-05-03 10:34:01 阅读:53422 作者:1803

网络编程的基本模型是C/S模型,它在两个进程之间进行相互通信。 其中,服务端提供位置信息(绑定IP地址和监听端口),客户端通过连接操作向服务端监听的地址发出连接请求,通过三次握手建立连接,如果连接成功,双方通过网络套接字

在基于传统同步阻塞模型的开发中,服务器套接字负责绑定IP地址,启动监听端口:套接字负责启动连接操作。 如果连接成功,则双方通过输入输出流进行同步块通信。

通过下图所示的通信模型图,熟悉以下BIO的服务器端通信模型。 采用BIO通信模式的服务器端通常在独立的Acceptor线程监听客户端连接,并收到客户端的连接请求后,为每个客户端创建新的线程进行链接处理,处理完成后,输出流这就是典型的要求响应通信模型。

这种模式最大的问题是缺乏灵活性。 随着客户端同时访问次数的增加,服务端线程数与客户端同时访问次数呈1:1比例关系。 线程是Java虚拟机非常宝贵的系统资源,因此随着线程数量的增加,系统性能急剧下降,同时访问量的增加,系统将无法创建线程堆栈溢出和新线程,最终导致进程崩溃在高性能服务器APP应用领域,一个需要同时连接成千上万个客户端,这种模式显然无法满足高性能、高并发访问的场景。

伪异步IO编程模型

为了改进线程间连接模型,后来产生了一种通过线程池或消息队列实现一个或多个线程来处理n个客户端的模型。 其基础通信机制仍然使用同步块IO,因此被称为“伪异步”。 以下u分析伪异步代码,以确定伪异步是否满足高性能、高并发访问的诉求。

为了解决并发块IO面临的一个链路需要一个线程处理的问题,有人优化了其线程模型,后端在一个线程池中处理来自多个客户端的请求访问,以及客户机数量M: 其中,m可以远大于n,并且通过在线程池中灵活配置线程资源并设置线程的最大值,可以防止由于大量并发访问而导致的线程耗尽。

使用线程池和任务队列,可以实现称为伪异步的IO通信框架。 其模型图如下图所示。

如果有新的客户端访问,则将客户端套接字封装到Task中并实现java.lang.Runnable接口。 JDK线程池维护消息队列和n个活动线程以处理消息队列中的任务。 线程池可以设置消息队列的大小和线程的最大数量,因此资源消耗是可控的,并且多个客户端同时访问不会耗尽或停机资源。

由于伪异步IO采用线程池实现,因此可以避免因为为每个请求创建独立线程而导致线程资源耗尽。 但本质上仍然是同步块模型,无法从根本上解决同步IO造成的通信线程阻塞问题。

NIO编程模型

Java NIO有一个重要的概念,即Selector,它是Java NIO编程的基础。 选择器也称为复用器,复用器提供选择准备好的任务的功能。 简而言之,选择器不断轮询已注册的通道。 如果一个通道上有新的TCP连接访问、读取和写入事件,则通道已就绪,可以轮询到选择器进行后续的IO操作。

复用器选择器可以同时轮询多个通道。 JDK使用epoll )代替传统的select实现),因此没有最大连接句柄限制。 这意味着只需在一个线程上负责Selector轮询,就可以访问成千上万个客户端。 这确实是一个非常大的进步。

使用NIO编程的优点可归纳如下。

客户端启动的连接操作是异步的,可以在向复用器注册的OP_CONNECT中等待后续结果。 不需要像以前的客户端那样同步阻止。

SocketChannel的所有读写操作都是异步的,如果没有可读写的数据,就不会同步等待,保持原样返回。 这样,IO通信线程就可以处理其他链路,而无需同步等待此链路可用。

线程模型优化: JDK的Selector是通过epoll在主要操作系统(如Linux )上实现的,因此没有连接数限制。 这意味着一个Selector线程可以同时处理成千上万个客户端连接,而性能不会随着客户端的增长而线性下降,因此它非常适合于高性能、同时处理成千上万个客户端连接

模型图如下所示:

但是,如果严格区分UNIX网络编程模型和JDK实现,它实际上被称为非阻塞IO,而不是异步非阻塞IO。

AIO编程模型

NIO2.0为UNIX网络编程事件驱动的IO提供了AIO,引入了新的异步通道概念,并提供了异步文件通道和异步套接字通道实现。 异步通道有两种获取操作结果的方法。

异步操作的结果由java.util.concurrent.Future类表示

在异步操作期间传递给java.nio.channels

JDK的下级层通过线程

池ThreadPoolExecutor来执行回调通知,异步Socket Channel是被动执行对象,我们不需要像NIO编程那样创建一个独立的IO线程来处理读写操作

不同IO模型对比

同步阻塞IO(BIO)伪异步IO非阻塞IO(NIO)异步IO(AIO)

客户端个数 : IO线程

1 : 1

M : N(M可以大于N)

M : 1(一个IO线程处理多个客户端连接)

M : 0(不需要启动额外的IO线程,被动回调)

IO类型(阻塞)

阻塞IO

阻塞IO

非阻塞IO

非阻塞IO

IO类型(同步)

同步IO

同步IO

同步IO(IO多路复用)

异步IO

API使用难度

简单

简单

非常复杂

复杂

调试难度

简单

简单

复杂

复杂

可靠性

非常差

吞吐量

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。