前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >传统 BIO (Blocking I/O)

传统 BIO (Blocking I/O)

作者头像
happyJared
发布2019-08-05 17:11:13
8510
发布2019-08-05 17:11:13
举报
文章被收录于专栏:happyJaredhappyJared

BIO (Blocking I/O) 是同步阻塞I/O模式,数据的读取写入必须阻塞在一个线程内等待其完成。

BIO 通信(一请求一应答)模型图如下:

传统 BIO 通信模型图

采用 BIO 通信模型 的服务端,通常由一个独立的 Acceptor 线程负责监听客户端的连接。一般是在 while(true) 循环中,服务端调用 accept() 方法,等待接收客户端的连接的监听请求,服务端一旦接收到一个连接请求,就可以建立通信套接字,并通过在这个通信套接字上进行读写操作,此时不能再接收其他客户端连接请求,只能等待同当前连接客户端的操作执行完成, 不过可以通过多线程来支持多个客户端的连接,如上图所示。

如果要让 BIO 通信模型 可以同时处理多个客户端请求,就必须使用多线程(主要原因是 socket.accept()socket.read()socket.write() 涉及的三个主要函数都是同步阻塞的),也就是说它在接收到客户端连接请求之后,为每个客户端创建一个新的线程进行链路处理,处理完成之后,通过输出流返回应答给客户端,线程销毁。这就是典型的 一请求一应答通信模型 。我们可以设想一下,如果这个连接不做任何事情的话,不就是会造成不必要的线程开销,这是可以通过 线程池机制 来改善的,线程池还可以让线程的创建和回收成本相对较低。使用 FixedThreadPool 可以有效控制线程的最大数量,保证了系统有限资源的控制,实现了 N(客户端请求数量):M(处理客户端请求的线程数量)的伪异步 I/O 模型(N 可以远远大于 M)。

再设想一下,当客户端并发访问量增加后,这种模型又会出现什么问题?

在 Java 虚拟机中,线程是宝贵的资源,创建和销毁成本都很高,除此之外,线程的切换成本也是很高的。尤其在 Linux 这样的操作系统中,线程本质上就是一个进程,创建和销毁线程都是重量级的系统函数。如果并发访问量增加,会导致线程数急剧膨胀,可能会导致线程堆栈溢出、创建新线程失败等问题,最终导致进程宕机或者僵死,不能对外提供服务。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019.08.04 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档