netty 小飞哥_netty 事件驱动(二)

2023-10-29 07:20

本文主要是介绍netty 小飞哥_netty 事件驱动(二),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

上一篇文件浅析了Netty中的事件驱动过程,这篇主要写一下异步相关的东东。

首先,什么是异步了?

异步的概念和同步相对。当一个异步过程调用发出后,调用者不能立刻得到结果。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者。

异步的好处是不会造成阻塞,在高并发情形下会更稳定和更高的吞吐量。

说到Netty中的异步,就不得不提ChannelFuture。Netty中的IO操作是异步的,包括bind、write、connect等操作会简单的返回一个ChannelFuture,调用者并不能立刻获得结果。

当future对象刚刚创建时,处于非完成状态。可以通过isDone()方法来判断当前操作是否完成。通过isSuccess()判断已完成的当前操作是否成功,getCause()来获取已完成的当前操作失败的原因,isCancelled()来判断已完成的当前操作是否被取消。

调用者可以通过返回的ChannelFuture来获取操作执行的状态,注册监听函数来执行完成后的操作。

其实同步的阻塞和异步的非阻塞可以直接通过代码看出:

这是一段阻塞的代码:

69c5a8ac3fa60e0848d784a6dd461da6.png

printTime("开始connect: ");//Start the connection attempt.

ChannelFuture future = bootstrap.connect(newInetSocketAddress(host, port));//Wait until the connection is closed or the connection attempt fails.

future.getChannel().getCloseFuture().awaitUninterruptibly();

printTime("connect结束: ");//Shut down thread pools to exit.

bootstrap.releaseExternalResources();

69c5a8ac3fa60e0848d784a6dd461da6.png

这段代码的输出结果是:

开始connect: 2013-07-17 14:45:28connect结束:2013-07-17 14:45:29

很明显的可以看出,connect操作导致整段代码阻塞了大概1秒。

以下这段是异步非阻塞的代码:

69c5a8ac3fa60e0848d784a6dd461da6.png

printTime("开始connect: ");//Start the connection attempt.

ChannelFuture future = bootstrap.connect(newInetSocketAddress(host, port));

future.addListener(newChannelFutureListener()

{public void operationComplete(finalChannelFuture future)throwsException

{

printTime("connect结束: ");

}

});

printTime("异步时间: ");//Shut down thread pools to exit.

bootstrap.releaseExternalResources();

69c5a8ac3fa60e0848d784a6dd461da6.png

输出结果是:

开始connect: 2013-07-17 14:50:09异步时间:2013-07-17 14:50:09connect结束:2013-07-17 14:50:09

可以明显的看出,在异步模式下,上面这段代码没有阻塞,在执行connect操作后直接执行到printTime("异步时间: "),随后connect完成,future的监听函数输出connect操作完成。

关于同步的阻塞和异步的非阻塞可以打一个很简单的比方,A向B打电话,通知B做一件事。

在同步模式下,A告诉B做什么什么事,然后A依然拿着电话,等待B做完,才可以做下一件事;

在异步模式下,A告诉B做什么什么事,A挂电话,做自己的事。B做完后,打电话通知A做完了。

如上面代码所显示的,ChannelFuture同时提供了阻塞和非阻塞方法,接下来就简单的分析一下各自是怎么实现的。

阻塞方法是await系列,这些方法要小心翼翼的使用,不可以在handler内调用这些方法,否则会造成死锁。

69c5a8ac3fa60e0848d784a6dd461da6.png

publicChannelFuture awaitUninterruptibly() {boolean interrupted = false;synchronized (this) {//循环等待到完成

while (!done) {

checkDeadLock();

waiters++;try{

wait();

}catch(InterruptedException e) {//不允许中断

interrupted = true;

}finally{

waiters--;

}

}

}if(interrupted) {

Thread.currentThread().interrupt();

}return this;

}

69c5a8ac3fa60e0848d784a6dd461da6.png

一个标志位,一个while循环,代码简洁明了。

非阻塞则是添加监听类ChannelFutureListener,通过覆盖ChannelFutureListener的operationComplete执行业务逻辑。

69c5a8ac3fa60e0848d784a6dd461da6.png

public void addListener(finalChannelFutureListener listener) {if (listener == null) {throw new NullPointerException("listener");

}boolean notifyNow = false;synchronized (this) {if(done) {

notifyNow= true;

}else{if (firstListener == null) {//listener链表头

firstListener =listener;

}else{if (otherListeners == null) {

otherListeners= new ArrayList(1);

}//添加到listener链表中,以便操作完成后遍历操作

otherListeners.add(listener);

}

......if(notifyNow) {//通知listener进行处理

notifyListener(listener);

}

}

69c5a8ac3fa60e0848d784a6dd461da6.png

然后当操作完成后直接遍历listener链表,把每个listener取出来执行。以setSuccess为例,如下:

69c5a8ac3fa60e0848d784a6dd461da6.png

public booleansetSuccess() {synchronized (this) {//Allow only once.

if(done) {return false;

}

done= true;//唤醒所有等待

if (waiters > 0) {

notifyAll();

}

}//通知所有listener

notifyListeners();return true;

}

69c5a8ac3fa60e0848d784a6dd461da6.png

69c5a8ac3fa60e0848d784a6dd461da6.png

private voidnotifyListeners() {if (firstListener != null) {//执行listener表头

notifyListener(firstListener);

firstListener= null;//挨个执行其余的listener

if (otherListeners != null) {for(ChannelFutureListener l: otherListeners) {

notifyListener(l);

}

otherListeners= null;

}

}

}

69c5a8ac3fa60e0848d784a6dd461da6.png

其实这部分代码的逻辑很简单,就是注册回调函数,当操作完成后自动调用回调函数,就达到了异步的效果。

这篇关于netty 小飞哥_netty 事件驱动(二)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/299117

相关文章

【Netty】netty中都是用了哪些设计模式

对于工程师来说,掌握并理解运用设计模式,是非常重要的,但是除了学习基本的概念之外,需要结合优秀的中间件、框架源码学习其中的优秀软件设计,这样才能以不变应万变。 单例模式 单例模式解决的对象的唯一性,一般来说就是构造方法私有化、然后提供一个静态的方法获取实例。 在netty中,select用于处理CONTINUE、SELECT、BUSY_WAIT 三种策略,通过DefaultSelectStra

Java语言的Netty框架+云快充协议1.5+充电桩系统+新能源汽车充电桩系统源码

介绍 云快充协议+云快充1.5协议+云快充1.6+云快充协议开源代码+云快充底层协议+云快充桩直连+桩直连协议+充电桩协议+云快充源码 软件架构 1、提供云快充底层桩直连协议,版本为云快充1.5,对于没有对接过充电桩系统的开发者尤为合适; 2、包含:启动充电、结束充电、充电中实时数据获取、报文解析、Netty通讯框架、包解析工具、调试器模拟器软件等; 源码合作 提供完整云快充协议源代码

Netty源码解析9-ChannelHandler实例之MessageToByteEncoder

MessageToByteEncoder框架可见用户使用POJO对象编码为字节数据存储到ByteBuf。用户只需定义自己的编码方法encode()即可。 首先看类签名: public abstract class MessageToByteEncoder<I> extends ChannelOutboundHandlerAdapter 可知该类只处理出站事件,切确的说是write事件

Netty源码解析8-ChannelHandler实例之CodecHandler

编解码处理器作为Netty编程时必备的ChannelHandler,每个应用都必不可少。Netty作为网络应用框架,在网络上的各个应用之间不断进行数据交互。而网络数据交换的基本单位是字节,所以需要将本应用的POJO对象编码为字节数据发送到其他应用,或者将收到的其他应用的字节数据解码为本应用可使用的POJO对象。这一部分,又和JAVA中的序列化和反序列化对应。幸运的是,有很多其他的开源工具(prot

Netty源码解析7-ChannelHandler实例之TimeoutHandler

请戳GitHub原文: https://github.com/wangzhiwubigdata/God-Of-BigData TimeoutHandler 在开发TCP服务时,一个常见的需求便是使用心跳保活客户端。而Netty自带的三个超时处理器IdleStateHandler,ReadTimeoutHandler和WriteTimeoutHandler可完美满足此需求。其中IdleSt

Netty源码解析6-ChannelHandler实例之LoggingHandler

LoggingHandler 日志处理器LoggingHandler是使用Netty进行开发时的好帮手,它可以对入站\出站事件进行日志记录,从而方便我们进行问题排查。首先看类签名: @Sharablepublic class LoggingHandler extends ChannelDuplexHandler 注解Sharable说明LoggingHandler没有状态相关变量,

Netty源码解析5-ChannelHandler

ChannelHandler并不处理事件,而由其子类代为处理:ChannelInboundHandler拦截和处理入站事件,ChannelOutboundHandler拦截和处理出站事件。ChannelHandler和ChannelHandlerContext通过组合或继承的方式关联到一起成对使用。事件通过ChannelHandlerContext主动调用如fireXXX()和write(msg)

Netty源码解析4-Handler综述

Netty中的Handler简介 Handler在Netty中,占据着非常重要的地位。Handler与Servlet中的filter很像,通过Handler可以完成通讯报文的解码编码、拦截指定的报文、 统一对日志错误进行处理、统一对请求进行计数、控制Handler执行与否。一句话,没有它做不到的只有你想不到的 Netty中的所有handler都实现自ChannelHandler接口。按照输入

Netty源码解析3-Pipeline

请戳GitHub原文: https://github.com/wangzhiwubigdata/God-Of-BigData Channel实现概览 在Netty里,Channel是通讯的载体,而ChannelHandler负责Channel中的逻辑处理。 那么ChannelPipeline是什么呢?我觉得可以理解为ChannelHandler的容器:一个Channel包含一个Chan

Netty源码解析2-Reactor

请戳GitHub原文: https://github.com/wangzhiwubigdata/God-Of-BigData 更多文章关注:多线程/集合/分布式/Netty/NIO/RPC Java高级特性增强-集合Java高级特性增强-多线程Java高级特性增强-SynchronizedJava高级特性增强-volatileJava高级特性增强-并发集合框架Java高级特性增强-