美文网首页后端开发
Netty学习--EventLoop和线程模型

Netty学习--EventLoop和线程模型

作者: 何何与呵呵呵 | 来源:发表于2019-01-19 17:26 被阅读58次
    EventLoop 接口
    EventLoop 的类层次结构

    在这个模型中,一个EventLoop 将由一个永远都不会改变的Thread 驱动,同时任务(Runnable 或者Callable)可以直接提交给EventLoop 实现,以立即执行或者调度执行。根据配置和可用核心的不同,可能会创建多个EventLoop 实例用以优化资源的使用,并且单个EventLoop 可能会被指派用于服务多个Channel。

    简单理解:一个EventLoop相当于一个循环,并有一条线程管理(Thread),当EventLoop添加或减少,线程也跟着改变.

    • Netty 4 中的I/O 和事件处理
      所有的I/O操作和事件都由已经被分配给了EventLoop的那个Thread来处理.
    • Netty 3 中的I/O 操作
      所有的出站(下游)事件都由调用线程处理,其可能是I/O 线程也可能是别的线程。
      问题一:多个出站事件同意调用一个ChannelHandle,因此需要在ChannelHandler 中对出站事件进行仔细的同步.
      问题二:当Channel.write()方法导致异常时,需要生成并触发一个exceptionCaught 事件。但是在Netty 3 的模型中,由于这是一个入站事件,需要在调用线程中执行代码,然后将事件移交给I/O 线程去执行,然而这将带来额外的上下文切换。
    任务调度
    • 使用EventLoop 调度任务
    Channel ch = ...
    ScheduledFuture<?> future = ch.eventLoop().schedule( // 调度任务在从现在开始的60 秒之后执行
    new Runnable() {
        @Override
        public void run() {
            System.out.println("60 seconds later");
        }
    }, 60, TimeUnit.SECONDS);
    
    实现细节
    • 线程管理
    EventLoop 的执行逻辑

    永远不要将一个长时间运行的任务放入到执行队列中,因为它将阻塞需要在同一线程上执行的任何其他任务。如果必须要进行阻塞调用或者执行长时间运行的任务,我们建议使用一个专门的EventExecutor。
    理解:一般EventLoop利用inEventLoop(Thread)绑定一条线程,如果需要多线程处理,则使用EventExecutor.

    • EventLoop/线程的分配
      1.异步传输
    用于非阻塞传输(如NIO 和AIO)的EventLoop 分配方式

    在当前实现中,使用顺序循环(round-robin)的方式进行分配以获取一个均衡的分布,并且相同的EventLoop可能会被分配给多个Channel。
    对于所有相关联的Channel 来说,ThreadLocal 都将是一样的。(同一个线程)

    2.阻塞传输

    阻塞传输(如OIO)的EventLoop 分配方式

    相关文章

      网友评论

        本文标题:Netty学习--EventLoop和线程模型

        本文链接:https://www.haomeiwen.com/subject/mqegdqtx.html