【Netty中异步的理解】

1. 同步和异步的理解

同步和异步关注的是消息通讯机制(synchronous communication / asynchronous communication )。

同步就是调用某个东西时,调用方得等待这个调用返回结果才能继续往后执行。

异步和同步相反,调用方不会等待得到结果,而是在调用者发出调用后,调用者可以继续执行后续操作,被调用者通过状态来通知调用者,或者调用者通过回调函数来处理这个调用的结果。

图解:

  • 同步执行

        

  • 异步执行

         

2. 同步异步与阻塞非阻塞的区别

同步和异步强调的是消息的通讯机制。所谓同步就是主线程发出一个“调用“时,该“调用”在没有得到结果之前,该“调用”就不返回。但是一旦调用返回,就是得到的调用的结果。

异步则相反,“调用”发出之后,这个调用就直接返回了,所有没有返回结果。换句话说就是,当一个异步过程调用发出后,调用者不会立刻得到结果,而是在“调用”发出后,“被调用者”通过状态,通知来告诉调用者或者通过回调函数来处理这个调用。

阻塞和非阻塞强调的是程序在等待调用结果时的状态。阻塞调用是指调用结果返回之前,当前线程会被挂起,直到调用线程返回结果。

非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。

对用同步调用来说,很多的时候当前线程还是激活的状态,只是从逻辑上当前函数没有返回而已,即同步等待时什么都不干,白白占用着资源。

2. Netty中异步理解

在Netty中所有的IO操作都是异步的,不能立刻得到IO操作的执行结果。如果我们要获取IO操作的结果,就需要注册一个监听器来监听其执行结果。在Java中的并发编程当中可以通过Future来进行异步结果的监听,但是在Netty当中时通过ChannelFuture来实现异步结果的监听。通过注册一个监听的方式来进行监听,当操作执行成功或者失败时监听会自动触发注册的监听事件。

ChannelFuture在开发当中时需要经常用到的,可以用来监听客户端连接服务端的结果反馈,Netty是异步操作,无法知道什么时候执行完成,因此可以通过ChannelFuture来进行执行结果的监听。在Netty当中的bind,writer,connect等操作都会简单的返回一个ChannelFuture。

核心方法:

序号方法描述
1addListener注册监听器,当操作已完成 (isDone 方法返回完成),将会通知指定的监听器;如果 Future 对象已完成,则通知指定的监听器
2removeListener移除监听器
3sync等待异步操作执行完毕
4await等待异步操作执行完毕
5isDone判断当前操作是否完成
6isSuccess判断已完成的当前操作是否成功
7isCancellable判断已完成的当前操作是否被取消
8cause获取已完成的当前操作失败的原因

sync () 和 await () 都是等待异步操作执行完成,那么它们有什么区别呢?

  1. sync () 会抛出异常,建议使用 sync ();
  2. await () 不会抛出异常,主线程无法捕捉子线程执行抛出的异常;

3.深入了解 ChannelFuture

3.1生命周期说明

Future 可以通过四个核心方法来判断任务的执行情况。

状态说明
isDone()任务是否执行完成,无论成功还是失败
isSuccess()任务是否执行采购
isCancelled()任务是否被取消
cause()获取执行异常信息

 执行过程状态的改变说明

当一个异步任务操作开始的时候,一个新的 future 对象就会被创建。

在开始的时候该 future 是处于未完成的状态,也就是说,isDone ()=false、isSuccess ()=false、isCancelled ()=false;

只要该任务中任何一种状态结束了,无论是说成功、失败、或者被取消,那么整个 Future 就会被标记为已完成

注意的是,如果执行失败那么 cause () 方法会返回异常信息的内容。

3. 深入了解 ChannelFuture

3.1 生命周期说明

Future 可以通过四个核心方法来判断任务的执行情况。

状态说明
isDone()任务是否执行完成,无论成功还是失败
isSuccess()任务是否执行采购
isCancelled()任务是否被取消
cause()获取执行异常信息

执行过程状态的改变说明

 当一个异步任务操作开始的时候,一个新的 future 对象就会被创建。在开始的时候该 future 是处于未完成的状态,也就是说,isDone ()=false、isSuccess ()=false、isCancelled ()=false;只要该任务中任何一种状态结束了,无论是说成功、失败、或者被取消,那么整个 Future 就会被标记为已完成。注意的是,如果执行失败那么 cause () 方法会返回异常信息的内容。

 

ChannelFuture channelFuture=bootstrap.connect("127.0.0.1",80);
channelFuture.addListener(new ChannelFutureListener() {
    public void operationComplete(ChannelFuture future) throws Exception {
        if(future.isDone()){
            if(future.isSuccess()){
                System.out.println("执行成功...");
            }else if(future.isCancelled()){
                System.out.println("任务被取消...");
            }else if(future.cause()!=null){
                System.out.println("执行出错:"+future.cause().getMessage());
            }
        }
    }
});

 3.2 ChannelFuture 父接口说明

 ChannelFuture 的类继承结构,具体如下所示:

public interface ChannelFuture extends Future<Void> {
    
}
public interface Future<V> extends java.util.concurrent.Future<V> {
    
}

 通过上面的继承关系,我们可以清晰的知道 ChannelFuture 其实最顶层的接口是来自 java 并发包的 Future,java 并发包下的 Future 需要手工检查执行结果是否已经完成,非常的繁琐,因此 Netty 把它进行了封装和完善,变成了自动的监听,用起来变的非常的简单。

java 并发包下的 Future 主要存在以下几个缺陷:

  1. 只允许手动通过 get () 来检查对应的操作是否已经完成,它是堵塞直到子线程完成执行并且返回结果;
  2. 只有 isDone () 方法判断一个异步操作是否完成,但是对于完成的定义过于模糊,JDK 文档指出正常终止、抛出异常、用户取消都会使 isDone () 方法返回真。并不能很好的区分到底是哪种状态。
  3. get () 方法是堵塞的,必须等待子线程执行完成才能往下执行。
//1.定义一个子线程,实现 Callable 接口
public class ThreadTest implements Callable<Integer>{
    @Override
    public Integer call(){
	    //打印
    	System.out.println(">>>>>>>>子线程休眠之前");
	    //休眠5秒
	    Thread.sleep(5000);
    	//打印
    	System.out.println(">>>>>>>>子线程休眠之后");
        return 1;
	}
}
//2.调用子线程处理
public static void main(String[] args){
    ThreadTest t=new ThreadTest();
    FutureTask<Integer> future=new FutureTask<Integer>(t);
    //2.1.开始执行子线程
    new Thread(future).start();
    
  	//2.2.手工返回结果
    int result=future.get();
    System.out.println(">>>>>>>>执行结果:"+result);
    //2.3.操作数据库
    userDao.updateStatus("1");
}

 执行结果:

>>>>>>>>子线程休眠之前
>>>>>>>>子线程休眠之后
>>>>>>>>执行结果:1

结论总结:

  1. 说明了 Java 并发包的 Future 要想获取异步执行结果,必须手工调用 get () 方法,此时虽然能获取执行结果,但是无法知道执行结果是成功还是失败;
  2. 使用 get () 获取执行结果,但是 get () 后面的业务则被堵塞,直到后面执行完毕才会往下执行,失去了异步操作提高执行效率的意义了。
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值