jdk源码分析 ——Selector深入分析

5 篇文章 0 订阅

1、spi方式的selector定制化
selector通过SelectorProvider创建的,通常不同安装版本的jdk中已经封装了相应的Select和SelectorProvider了,通过spi的方式进行扩展。(PS:spi是一种jdk提供的低侵入方式的扩展实现,目前已经在大多数的框架中使用了,类似dubbo框架也使用该方式,让用户进行更好的定制化实现)

2、selector的原理
NIO极大提高了IO的并发,且在各大操作系统都已经有了相应的支持,类似linux的select、pool、epoll等,windows的IOCP等。在NIO中又包含了两种机制,一种是reactor;另外一种是proactor,这两种方式的主要区别是:IO数据是自己去内核读取,还是提供用户空间数据缓冲区,让内核读取。

在目前的jdk版本中也最大化的利用了操作系统的NIO机制,封装成了统一的接口供java应用使用,该实现机制是在操作系统的NIO的reactor或者proactor机制之上,再次封装了一次,并创建相应的socket事件的映射即可。

3、selector多线程特性
在jdk中自带的selector的方法是线程安全的,可以多线程调用selector的方法,但是从我个人的实践来看,其实没有必要多线程调用,其实单个线程就可以了,最主要是select出来的Set这个可以进行多线程的处理,但是该集合是非线程安全的,所以在多线程使用的时候需要进行同步的操作

4、关于多线程accept的理解
为什么需要多线程的accept?这个问题需要仔细的分析,目前很多框架都是用了多线程的accept,但是使用多线程的accept是有条件的,那就是在某一个线程accept之后之后,会对新的socket进行一些简单的认证的操作等,操作完了之后再把该socket放入业务线程池。由于这些操作需要花费一定的时间,所以这个时候可以把serversocket让出来,让其他的线程accept。

那么问题来了:那为什么不可以单个线程accept,然后将accept的socket直接丢到业务线程池呢?
其实这样也是可以的,但是为了更好的符合单一职责的原则,业务线程池应该是主要负责业务处理的,那么像socket的一些合法性检测等操作应该使用单独的线程池进行,既然有了独立的线程池,而且这些检测本身也不是特别耗时,所以就可以把accept也放到该线程中了。

但是在很早之前的操作系统中这种多线程的accept会出现“惊群”效应,目前很多操作系统已经解决了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值