- 浏览: 981017 次
文章分类
- 全部博客 (428)
- Hadoop (2)
- HBase (1)
- ELK (1)
- ActiveMQ (13)
- Kafka (5)
- Redis (14)
- Dubbo (1)
- Memcached (5)
- Netty (56)
- Mina (34)
- NIO (51)
- JUC (53)
- Spring (13)
- Mybatis (17)
- MySQL (21)
- JDBC (12)
- C3P0 (5)
- Tomcat (13)
- SLF4J-log4j (9)
- P6Spy (4)
- Quartz (12)
- Zabbix (7)
- JAVA (9)
- Linux (15)
- HTML (9)
- Lucene (0)
- JS (2)
- WebService (1)
- Maven (4)
- Oracle&MSSQL (14)
- iText (11)
- Development Tools (8)
- UTILS (4)
- LIFE (8)
最新评论
-
Donald_Draper:
Donald_Draper 写道刘落落cici 写道能给我发一 ...
DatagramChannelImpl 解析三(多播) -
Donald_Draper:
刘落落cici 写道能给我发一份这个类的源码吗Datagram ...
DatagramChannelImpl 解析三(多播) -
lyfyouyun:
请问楼主,执行消息发送的时候,报错:Transport sch ...
ActiveMQ连接工厂、连接详解 -
ezlhq:
关于 PollArrayWrapper 状态含义猜测:参考 S ...
WindowsSelectorImpl解析一(FdMap,PollArrayWrapper) -
flyfeifei66:
打算使用xmemcache作为memcache的客户端,由于x ...
Memcached分布式客户端(Xmemcached)
netty 事件执行器组和事件执行器定义及抽象实现:http://donald-draper.iteye.com/blog/2391257
netty 多线程事件执行器组:http://donald-draper.iteye.com/blog/2391270
netty 多线程事件循环组:http://donald-draper.iteye.com/blog/2391276
netty 抽象调度事件执行器:http://donald-draper.iteye.com/blog/2391379
netty 单线程事件执行器初始化:http://donald-draper.iteye.com/blog/2391895
netty 单线程事件执行器执行任务与graceful方式关闭:http://donald-draper.iteye.com/blog/2392051
引言:
上一篇文章看了单线程事件执行器的任务执行与执行器关闭,先来回顾一下:
单线程事件执行器,执行任务,首先判断任务是否为null,为空抛出空指针异常,否则,判断线程是否在当前事件循环中,在则添加任务到任务队列,否则开启当前单线程事件执行器,并添加任务到任务队列,如果此时事件执行器已关闭,并可以移除任务,则抛出拒绝执行器任务异常;如果需要启动事件执行器唤醒线程,则添加唤醒线程到任务队列。
添加,移除,poll任务操作,实际委托给任务队列,添加,移除hook线程操作委托给关闭hooks线程集合。
单线程事件执行器take任务,首先从调度任务队列peek头部调度任务,如果任务不为空,则获取调度任务延时时间,如果延时时间大于0,则从任务队列超时poll任务,否则从调度任务队列抓取调度任务,添加到任务队列,并从任务队列poll任务;如果调度任务为空,则从任务队列take一个任务,如果是唤醒任务,则忽略。
关闭单线程执行器,首先检查间隔、超时时间,时间单元参数,并且间隔时间要小于超时时间,如果已经关闭,则返回异步关闭任务结果,否则检查线程是否在当前事务循环中,如果是则更新状态为正在关闭,并计算计算关闭间隔和超时时间。
今天来看一下单线程事件循环SingleThreadEventLoop:
从上面来看,单线程事件循环SingleThreadEventLoop,继承了单线程事件执行器,实现了事件循环接口,内部一个事件循环任务队列,我们可以把单线程事件循环看为一个简单的事件执行器,单线程事件循环中多了一个通道注册的方法,实际注册工作委托给通道关联的UnSafe。
再来看一下Nio事件循环的定义:
nio事件循环实际为一个单线程事件循环,这样做的目的是,事件循环关联的通道注册到一个
选择器,可以复用循环事件,即保证通道的IO操作线程安全。
总结:
单线程事件循环SingleThreadEventLoop,继承了单线程事件执行器,实现了事件循环接口,
内部一个事件循环任务队列,我们可以把单线程事件循环看为一个简单的事件执行器,单线程事件循环中多了一个通道注册的方法,实际注册工作委托给通道关联的UnSafe。
netty 多线程事件执行器组:http://donald-draper.iteye.com/blog/2391270
netty 多线程事件循环组:http://donald-draper.iteye.com/blog/2391276
netty 抽象调度事件执行器:http://donald-draper.iteye.com/blog/2391379
netty 单线程事件执行器初始化:http://donald-draper.iteye.com/blog/2391895
netty 单线程事件执行器执行任务与graceful方式关闭:http://donald-draper.iteye.com/blog/2392051
引言:
上一篇文章看了单线程事件执行器的任务执行与执行器关闭,先来回顾一下:
单线程事件执行器,执行任务,首先判断任务是否为null,为空抛出空指针异常,否则,判断线程是否在当前事件循环中,在则添加任务到任务队列,否则开启当前单线程事件执行器,并添加任务到任务队列,如果此时事件执行器已关闭,并可以移除任务,则抛出拒绝执行器任务异常;如果需要启动事件执行器唤醒线程,则添加唤醒线程到任务队列。
添加,移除,poll任务操作,实际委托给任务队列,添加,移除hook线程操作委托给关闭hooks线程集合。
单线程事件执行器take任务,首先从调度任务队列peek头部调度任务,如果任务不为空,则获取调度任务延时时间,如果延时时间大于0,则从任务队列超时poll任务,否则从调度任务队列抓取调度任务,添加到任务队列,并从任务队列poll任务;如果调度任务为空,则从任务队列take一个任务,如果是唤醒任务,则忽略。
关闭单线程执行器,首先检查间隔、超时时间,时间单元参数,并且间隔时间要小于超时时间,如果已经关闭,则返回异步关闭任务结果,否则检查线程是否在当前事务循环中,如果是则更新状态为正在关闭,并计算计算关闭间隔和超时时间。
今天来看一下单线程事件循环SingleThreadEventLoop:
package io.netty.channel; import io.netty.util.concurrent.RejectedExecutionHandler; import io.netty.util.concurrent.RejectedExecutionHandlers; import io.netty.util.concurrent.SingleThreadEventExecutor; import io.netty.util.internal.ObjectUtil; import io.netty.util.internal.SystemPropertyUtil; import io.netty.util.internal.UnstableApi; import java.util.Queue; import java.util.concurrent.Executor; import java.util.concurrent.ThreadFactory; /** * Abstract base class for {@link EventLoop}s that execute all its submitted tasks in a single thread. 单线程事件循环在单个线程中执行所有提交的任务 * */ public abstract class SingleThreadEventLoop extends SingleThreadEventExecutor implements EventLoop { protected static final int DEFAULT_MAX_PENDING_TASKS = Math.max(16, SystemPropertyUtil.getInt("io.netty.eventLoop.maxPendingTasks", Integer.MAX_VALUE)); //当前循环任务队列 private final Queue<Runnable> tailTasks; //下面几个构造方法与单线程事件执行器基本相同,就不说了 protected SingleThreadEventLoop(EventLoopGroup parent, ThreadFactory threadFactory, boolean addTaskWakesUp) { this(parent, threadFactory, addTaskWakesUp, DEFAULT_MAX_PENDING_TASKS, RejectedExecutionHandlers.reject()); } protected SingleThreadEventLoop(EventLoopGroup parent, Executor executor, boolean addTaskWakesUp) { this(parent, executor, addTaskWakesUp, DEFAULT_MAX_PENDING_TASKS, RejectedExecutionHandlers.reject()); } protected SingleThreadEventLoop(EventLoopGroup parent, ThreadFactory threadFactory, boolean addTaskWakesUp, int maxPendingTasks, RejectedExecutionHandler rejectedExecutionHandler) { super(parent, threadFactory, addTaskWakesUp, maxPendingTasks, rejectedExecutionHandler); tailTasks = newTaskQueue(maxPendingTasks); } protected SingleThreadEventLoop(EventLoopGroup parent, Executor executor, boolean addTaskWakesUp, int maxPendingTasks, RejectedExecutionHandler rejectedExecutionHandler) { super(parent, executor, addTaskWakesUp, maxPendingTasks, rejectedExecutionHandler); tailTasks = newTaskQueue(maxPendingTasks); } //获取所属事件循环组 @Override public EventLoopGroup parent() { return (EventLoopGroup) super.parent(); } //获取当前事件循环 @Override public EventLoop next() { return (EventLoop) super.next(); } //注册通道 @Override public ChannelFuture register(Channel channel) { return register(new DefaultChannelPromise(channel, this)); } //注册通道 @Override public ChannelFuture register(final ChannelPromise promise) { ObjectUtil.checkNotNull(promise, "promise"); //委托给通道关联的UnSafe,这个具体我们在后面再说 promise.channel().unsafe().register(this, promise); return promise; } //此注册方法已丢弃 @Deprecated @Override public ChannelFuture register(final Channel channel, final ChannelPromise promise) { if (channel == null) { throw new NullPointerException("channel"); } if (promise == null) { throw new NullPointerException("promise"); } channel.unsafe().register(this, promise); return promise; } /** * Adds a task to be run once at the end of next (or current) {@code eventloop} iteration. *在事件循环迭代后,运行指定任务 * @param task to be added. */ @UnstableApi public final void executeAfterEventLoopIteration(Runnable task) { ObjectUtil.checkNotNull(task, "task"); if (isShutdown()) { //事件循环关闭,则抛出拒绝执行异常 reject(); } //如果添加任务到任务队列失败,则拒绝执行任务 if (!tailTasks.offer(task)) { reject(task); } //如果需要为任务,启动唤醒线程,则添加唤醒线程到任务队列 if (wakesUpForTask(task)) { wakeup(inEventLoop()); } } /** * Removes a task that was added previously via {@link #executeAfterEventLoopIteration(Runnable)}. *在在事件循环迭代后,移除指定任务 * @param task to be removed. * * @return {@code true} if the task was removed as a result of this call. */ @UnstableApi final boolean removeAfterEventLoopIterationTask(Runnable task) { return tailTasks.remove(ObjectUtil.checkNotNull(task, "task")); } //是否启动唤醒任务线程 @Override protected boolean wakesUpForTask(Runnable task) { return !(task instanceof NonWakeupRunnable); } //在运行所有任务结束后,执行tailTasks任务队列中的任务 @Override protected void afterRunningAllTasks() { runAllTasksFrom(tailTasks); } //判断tailTasks任务队列中是否有任务 @Override protected boolean hasTasks() { return super.hasTasks() || !tailTasks.isEmpty(); } //获取任务队列中的任务数 @Override public int pendingTasks() { return super.pendingTasks() + tailTasks.size(); } /** * Marker interface for {@link Runnable} that will not trigger an {@link #wakeup(boolean)} in all cases. 标记线程不会触发唤醒线程 */ interface NonWakeupRunnable extends Runnable { } }
从上面来看,单线程事件循环SingleThreadEventLoop,继承了单线程事件执行器,实现了事件循环接口,内部一个事件循环任务队列,我们可以把单线程事件循环看为一个简单的事件执行器,单线程事件循环中多了一个通道注册的方法,实际注册工作委托给通道关联的UnSafe。
再来看一下Nio事件循环的定义:
/** * {@link SingleThreadEventLoop} implementation which register the {@link Channel}'s to a * {@link Selector} and so does the multi-plexing of these in the event loop. * */ public final class NioEventLoop extends SingleThreadEventLoop {
nio事件循环实际为一个单线程事件循环,这样做的目的是,事件循环关联的通道注册到一个
选择器,可以复用循环事件,即保证通道的IO操作线程安全。
总结:
单线程事件循环SingleThreadEventLoop,继承了单线程事件执行器,实现了事件循环接口,
内部一个事件循环任务队列,我们可以把单线程事件循环看为一个简单的事件执行器,单线程事件循环中多了一个通道注册的方法,实际注册工作委托给通道关联的UnSafe。
发表评论
-
netty NioSocketChannel解析
2017-09-29 12:50 1321netty 抽象BootStrap定义:http://dona ... -
netty Pooled字节buf分配器
2017-09-28 13:00 2057netty 字节buf定义:http://donald-dra ... -
netty Unpooled字节buf分配器
2017-09-26 22:01 2444netty 字节buf定义:http://donald-dra ... -
netty 抽象字节buf分配器
2017-09-26 08:43 1316netty 字节buf定义:http:// ... -
netty 复合buf概念
2017-09-25 22:31 1310netty 字节buf定义:http://donald-dra ... -
netty 抽象字节buf引用计数器
2017-09-22 12:48 1594netty 字节buf定义:http://donald-dra ... -
netty 抽象字节buf解析
2017-09-22 09:00 1844netty 通道接口定义:http://donald-drap ... -
netty 资源泄漏探测器
2017-09-21 09:37 1397netty 通道接口定义:http://donald-drap ... -
netty 字节buf定义
2017-09-20 08:31 2834netty 通道接口定义:http://donald-drap ... -
netty 默认通道配置后续
2017-09-18 08:36 2177netty 通道接口定义:http://donald-drap ... -
netty 默认通道配置初始化
2017-09-17 22:51 2037netty 通道接口定义:http://donald-drap ... -
netty 通道配置接口定义
2017-09-17 14:51 1078netty 通道接口定义:http://donald-drap ... -
netty NioServerSocketChannel解析
2017-09-16 13:01 1877netty ServerBootStrap解析:http:// ... -
netty 抽象nio消息通道
2017-09-15 15:30 1218netty 通道接口定义:http:/ ... -
netty 抽象nio字节通道
2017-09-14 22:39 1202netty 通道接口定义:http:/ ... -
netty 抽象nio通道解析
2017-09-14 17:23 957netty 通道接口定义:http://donald-drap ... -
netty 抽象通道后续
2017-09-13 22:40 1309netty Inboudn/Outbound通道Inv ... -
netty 通道Outbound缓冲区
2017-09-13 14:31 2189netty 通道接口定义:http:/ ... -
netty 抽象Unsafe定义
2017-09-12 21:24 1076netty 通道接口定义:http:/ ... -
netty 抽象通道初始化
2017-09-11 12:56 1855netty 管道线定义-ChannelPipeline:htt ...
相关推荐
EventLoop可以视为一个无限循环,它会处理多个连接上的事件,并与一个或多个线程绑定。在Netty中,通常会创建多个EventLoop来充分利用多核处理器的性能,其中每个EventLoop都由一个单独的线程来驱动。 在Netty的...
EventLoop是Netty的核心组件,它是一个单线程执行任务的循环,负责处理I/O事件并分发到对应的处理器。每个EventLoop都包含一个Selector,用于监听多个通道的事件。通过多路复用技术,EventLoop可以高效地处理大量...
它使用了单线程事件循环(Event Loop)处理多个连接,大大减少了线程上下文切换的开销。同时,Netty的线程池设计可以确保并发处理大量连接时的高效性。 标签"java"表明这是Java编程语言的一部分,"netty-all"意味着...
Netty使用单线程的事件循环来处理多个Channel,提高并发性能。 5. **Pipeline**:通道处理管道,由一系列处理器(ChannelHandler)组成。每个处理器负责处理特定类型的事件或数据,可以自定义添加、删除或替换...
Netty使用EventLoopGroup作为其多线程模型的基础,通常包含一个BossGroup负责接受新的连接,而多个WorkerGroup则处理已连接的通道上的读写事件。每个EventLoop都是一个独立的线程,它们负责处理分配给它们的通道。...
事件循环是Netty中的核心组件,负责处理I/O事件,并将这些事件分发到对应的处理器。管道则是一系列处理器的链,每个处理器(ChannelHandler)可以处理特定类型的事件,如读取数据、写入数据或者处理异常。 在Netty...
11. **Reactor 模式**: Netty 基于单线程或多线程的 Reactor 模型运行,实现了高效的并发处理。 12. **Extensibility**: Netty 的设计使其易于扩展,可以轻松地添加新的协议支持或者自定义处理逻辑。 在开发过程中...
而Netty采用了一种称为“事件循环”(Event Loop)的设计,通过少量的线程就能处理大量并发连接,极大地提高了系统的性能和效率。 Netty的事件模型基于“Reactor”模式,其中包含了四个主要组件:处理器(Handler)...
EventLoop是Netty的事件循环,负责调度和执行任务。 Netty的异步模型是其效率的关键。通过使用NIO的非阻塞I/O,Netty能够在单个线程中处理多个连接,极大地提高了并发能力。同时,Netty的Buffer类提供了一种高效的...
4. **线程模型**:Netty 使用单线程模型的事件循环,每个事件循环负责处理多个通道的事件,降低了线程切换的开销。 5. **零拷贝**:通过直接内存和FileRegion的使用,Netty实现了在操作系统级别减少数据复制,提高...
4. **EventLoop和EventLoopGroup**:EventLoop是执行事件处理器(如ChannelHandler)的单线程循环。EventLoopGroup是一组EventLoop的集合,用于分配事件处理器并处理网络事件。 5. **Pipeline**:Netty的处理链模式...
- **EventLoop(事件循环)**:Netty的事件驱动模型基于单线程的事件循环,它负责处理I/O事件并调度任务。 - **Channel(通道)**:代表一个打开的连接,可以进行读写操作。 - **Buffer(缓冲区)**:Netty自定义...
- **线程模型优化**: 通过单线程的EventLoop模型,减少了线程上下文切换的开销。 6. **Netty在实际应用中的案例** Netty广泛应用于分布式系统、游戏服务器、流媒体服务、微服务框架等领域,例如 Dubbo 和 Spring ...
- **NIO(Non-blocking I/O)**:Netty是基于Java NIO构建的,NIO允许单线程处理多个通道,减少了线程创建和销毁的开销。 - **Channel**:Netty中的核心概念,表示网络连接,如TCP连接或UDP套接字。 - **Event...
4. **线程模型**:Netty 的事件循环模型使用单线程处理多个连接,减少了线程上下文切换的开销,提高了系统性能。 5. **强大的API**:Netty 提供了一套简单易用且强大的API,使得编写网络应用变得直观而简洁。 6. *...
- **线程模型**: Netty采用了单线程模型,减少了线程上下文切换的开销,提高了系统资源利用率。 - **异常处理**: 系统化的异常处理机制,使代码更加健壮,简化了错误处理。 3. **关键知识点** - **...
2. **EventLoop(事件循环)**:Netty中的事件循环是其异步模型的基础。每个EventLoop负责处理一组通道(Channels),并在这些通道上有事件发生时执行相应的处理器(Handlers)。 3. **Channel(通道)**:在Netty...
5. **多线程模型**: Netty 的事件循环(EventLoop)是基于单线程的,但可以有多个 EventLoop 组成一个 EventLoopGroup,这样可以并发处理多个连接。 6. **编解码器**: 在 UDP 应用中,你可能需要自定义编解码器来...
6. **线程模型**:Netty的线程模型设计精巧,包括NIO线程池和单线程EventLoop组,确保了线程安全和性能优化。通过合理的线程分配,Netty能够有效地处理并发任务,避免了线程间的上下文切换开销。 7. **实战案例**:...