NIO中的同步与非阻塞

脑子烧的慌

早上看到了一些Java序列化的应用,不知道怎么那个人扯到了NIO,然后我突然想起了SOA中的的RPC服务,这种远端提供服务时很有可能会用到序列化传输对象,然后又为了在分布式条件下具有高并发的性能,所以很有可能会用到NIO来传输数据。
接着,我就开始回忆NIO的一些细节,突然间就不能想起来NIO提供同步还是非同步,阻塞还是非阻塞IO了。
查资料查了一堆,概念定义解析看了不少,人是越来越懵逼了,究竟这些概念是什么意思,怎么理解,怎么应用?看了好久,脑子感觉明显发热,好在后面看了知乎上一个人的解释,瞬间就是一个醍醐灌顶,一下子理顺了之前的思维。鉴于过程艰辛困苦,在这里特意总结一下。

NIO是同步非阻塞IO

NIO是同步非阻塞式IO
NIO是同步非阻塞式IO
NIO是同步非阻塞式IO
首先我要把这句话说三遍,因为之前我一度忘记了NIO的特点。但是我个人之前对与这个同步与非阻塞体现在哪里不是很理解。

我们都知道,NIO是有三个基本的构件:SelectorChannelBuffer。Channel向Selector中注册不同的兴趣事件,然后Selector会负责监听Channel中是否有注册的事件发生,如果有需要读写的操作,Channel又会使用Buffer来缓存数据,用于之后操作;Selector可以被多个Channel注册,这样一个主线程中的Selector就可以监视多个Channel(可能会位于多个线程)发生的事件。

在NIIO基本概念的基础上,我们来看这些在IO中常见词的概念

同步与异步

站在程序的角度上,

  • 同步:用户程序在发起操作后,需要不断的轮询操作是否完成(或准备就绪),如果没有完成(就绪)导致程序“卡住”,无法继续向下运行;直到操作完成才通知程序继续
  • 异步:用户程序发起操作后,便不再关注操作的具体是否执行以及执行的内容;当操作完成之后,会自动回调或其它通知方式来通知程序

阻塞与非阻塞

站在线程的角度上,

  • 阻塞:当主线程发起一个操作时,具体执行时该线程就一直等,直到等到实际的操作完成之后,线程才会继续
  • 非阻塞:当一个主线程发起操作后,具体执行的方法会分出独立的线程去执行这个操作,主线程是继续向下运行的,而不是傻傻的等待

再来看同步与非阻塞

看完了上面的概念后,可以注意到的是,同步与非阻塞关注的点不同,同步与异步是说消息的通知机制,而阻塞与非阻塞说的是线程的状态

回过头来看NIO的同步与非阻塞

首先我们要先明确一点,Java最底层的IO操作是同步的,但是NIO是一个经过包装的IO操作,是在selector机制实现的事件驱动包装下,对外提供同步非阻塞的功能

具体体现在,Selector的select()方法会轮询Channel中的事件是否就绪(这是同步),在主线程中的Selector可以监听多个Channel注册的事件,如果有事件发生自然会分配Channel去处理,这样主线程并不会阻塞(这是非阻塞)

MyCat中的NIO应用

MyCat的通信模型中,是有使用到NIO的,对应了Reactor模式的通信机制
NIO中的同步与非阻塞_第1张图片

  • NIOAcceptor负责轮询是否有连接事件,如果有就将连接放到队列中交给NIOReactor负责,NIOAcceptor继续轮询接下来是否有连接(这是基于Reactor事件驱动的编程模型提供了异步操作
  • 后端NIOConnector也会负责后端连接事件,同样把连接放到队列中交给NIOReactor处理
  • NIOReactor会分出独立处理读写事件的RW线程来完成具体的读或者写
  • 读写后会将数据交给专门处理业务的工作线程去通过Handler的方法进行下一步的处理

其实上面提到了MyCat的通信模块与线程模块,具体的线程模块会在以后分析

我说

首先是一种混沌之后的豁然开朗,随后而来的是一种劫后余生的幸运。之前确实是被绕晕了,像是之前的Java中的编码问题一样。被绕晕过的人都会懂,脑海中是各式各样的概念,杂七杂八的混杂在一起,理不出思绪,甚至是原来已经具有的理解也被忘记或者颠覆。我很清楚这样下去很有可能在耐心耗尽之时匆匆得出一个错误的结论,这对个体知识体系的建立是灾难级别的打击。不过回过头来也只能说这是对于基本概念理解的问题,今天我解决了,写下了这篇自己的总结,希望可以给别人提供一点点微小的帮助。

知乎链接:Java NIO不是同步非阻塞IO吗,怎么还会….

你可能感兴趣的:(NIO,MyCat)