java 同步非阻塞的nio中包含阻塞的selector的理解

nio与selector的联系
NIO自从JDK1.4版本以来就添加的一个非阻塞I/O框架,NIO是Java为解决网络通讯中高并发问题的一个类库,Selector是java NIO的一个组件,用于检查一个或多个NIO Channel的状态是否处于可读、可写。如此可以实现单线程管理多个channels,也就是可以管理多个网络链接,所以Selecotr是实现了多路复用的关键。

纠结点
java nio是非阻塞的,但是java的selector组件确实阻塞的(当线程进入阻塞状态,是不占用CPU资源的。多么nice的设计理念),那为什么还要称java nio是非阻塞的呢?

解释
java nio说的非阻塞指的是对于io操作来说是非阻塞的,传统bio在进行socket.accept()、socket.read()、socket.write()三个主要函数时都是同步阻塞的,多说一点因为是同步阻塞所以如果是单线程、且io一直没有数据那么系统将会被一直挂在那里。
而nio一般会有很多io操作,当有任何一个io有数据 ,selector就被唤醒,所以在这条线程中,当io1没有数据处于等待时,io2可能正在被处理,所以这条线程并没有被这个io1阻塞。
所以说java nio说的同步非阻塞指的是对于io操作来说,而并非对于整个java nio 来说都是非阻塞的
因为java nio 的selector是阻塞的,虽然说selector是阻塞的但是它实现了多路复用,而且相对于传统io,nio还节省了线程,以及线程之间切换带来的系统消耗。
所以通过分析,同步非阻塞的nio中包含阻塞的selector,只是关注的点不同而已,而且严格意义上将java nio应该说是多路复用,而不是同步非阻塞。

扩展

为什么说线程是很贵的资源?

  1. 线程的创建和销毁成本很高,在Linux这样的操作系统中,线程本质上就是一个进程。创建和销毁都是重量级的系统函数。
  2. 线程本身占用较大内存,像Java的线程栈,一般至少分配512K~1M的空间,如果系统中的线程数过千,恐怕整个JVM的内存都会被吃掉一半。
  3. 线程的切换成本是很高的。操作系统发生线程切换的时候,需要保留线程的上下文,然后执行系统调用。如果线程数过高,可能执行线程切换的时间甚至会大于线程执行的时间,这时候带来的表现往往是系统load偏高、CPU sy使用率特别高(超过20%以上),导致系统几乎陷入不可用的状态。
  4. 容易造成锯齿状的系统负载。因为系统负载是用活动线程数或CPU核心数,一旦线程数量高但外部网络环境不是很稳定,就很容易造成大量请求的结果同时返回,激活大量阻塞线程从而使系统负载压力过大。

传统bio的缺陷
传统bio依赖于多线程,多线程一般都使用线程池,可以让线程的创建和回收成本相对较低。在活动连接数不是特别高(小于单机1000)的情况下,这种模型是比较不错的,可以让每一个连接专注于自己的I/O并且编程模型简单,也不用过多考虑系统的过载、限流等问题。线程池本身就是一个天然的漏斗,可以缓冲一些系统处理不了的连接或请求。但是当面对十万甚至百万级连接的时候,传统的BIO模型是无能为力的。

参考文章:浅谈java nio(美团技术团队)

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值