采纳答案成功!
向帮助你的同学说点啥吧!感谢那些助人为乐的人
按照我的理解是readNextMessage只需要调用一次,然后有消息来的时候这个onCompleted方法就会被调用,我的理解问题出在哪?
这个地方在于对于Selector的理解。
当我们在Selector上注册一个监听后,如果事件就绪就会从select方法中得到。此时可以进行事件处理。但是这里有一个较大的问题,如果在多并发的情况下,我们一个线程专门负责Selector.select()操作,那么当有通道就绪时此时我们不断的调用Selector.select()将每次都得到这个就绪的通道。
我们的流程是:A线程Selector.select()得到就绪通道,将通道丢进线程池,等待线程池中的线程 B、C、D等运行。这个过程肯定不是单线的,而是多并发的。
那么当线程池还没处理完这个事件之前,我们每次Selector.select()都会得到这个通道;然后又会重复丢进线程池;这就有矛盾了,一旦发生这样的事情,那么就会出现同一个通道的数据被多个线程同时操作的情况,也就会出现数据混乱问题。对于一段字符串:“Hello”可能一个线程读取了其中一部分。但是却无法正确组合在一起。
那么这个时候我们在Selector.select()之后就做了一件事件,将已就绪的通道全部解除注册,那么下一次调度Selector.select()就不会得到这些就绪的通道了,从而避免上述问题。
当然这样的做法就需要有一个完整的闭环:
注册-等到Selector.select()-已就绪-解除注册-丢进线程池-等待线程调度-处理调度-读取数据-再次注册下一次调度
所以我们需要在完成方法调度时再次调用:
readNextMessage
好的,理解了谢谢老师,那么如果已就绪的通道全部解除注册,这时这些解除注册的通道对应的客户端有消息来了就得不到监听了,这些消息会被遗弃掉吗?还是说当这些通道重新注册时(如果之前有消息来了)又会处于就绪状态?0
好的,理解了谢谢老师,那么如果已就绪的通道全部解除注册,这时这些解除注册的通道对应的客户端有消息来了就得不到监听了,这些消息会被遗弃掉吗?还是说当这些通道重新注册时(如果之前有消息来了)又会处于就绪状态?
是的,消息不会丢,本地读取会读取完全,如果本次读取没有读取完全,再次注册会继续返回已就绪。
好的,谢谢!
登录后可查看更多问答,登录/注册
理论+实践,系统且深入掌握Socket核心技术,从容应对各种Socket应用场景的不二之选
2.8k 1
1.8k 7
1.7k 5
1.9k 13
1.1k 13