zoukankan      html  css  js  c++  java
  • vertx的Future模式的实现FutureImpl分析

    问题

    在使用异步编程的时候,Future模式实现需要注意几个问题:

    • 当提前已经Complete,但是还没有设置Handler,这时候需要在设置Handler的时候执行Handler方法
    • 当提前已经设置了Handler,在执行Complete方法的时候,需要执行Handler方法

    解决

    其实,只要在Complete方法里面判断当前有没有设置Handler,如果设置了,那就执行Handler,如果没有,就没有,然后在设置Handler方法里面判断当前有没有执行完成,如果执行完成,那就直接执行Handler,如果没有,就没有…当然,执行的时候要考虑线程安全问题,我们可以直接使用synchronized关键字来进行线程安全问题处理,因为在1.8之后性能也不是很低…

    我们看vert.x里面的Future的具体实现

    首先我们看Future的实现:
    在这里插入图片描述
    有个叫FutureImpl,应该就是具体的简单实现,当然,我们也可以直接实现,然后使用自己封装的Futrure去完成需求,当然,如果有一些定制的需求,建议直接继承FutureImpl,去重写对应方法好了…
    线看一看属性:
    在这里插入图片描述
    比较简单,就是是否成功,失败,设置的Handler,结果和异常信息…

    先看isComplete方法,

    在这里插入图片描述
    如果不使用两个属性,成功失败,会造成什么情况,默认都是false,我就不知道,到底是失败了还是没有执行…如果执行失败那么failed会是true,
    在这里插入图片描述

    再看setHandler方法

    按照我们刚才说的,setHandler,只需要判断将当前handler设置进去,然后判断有没有执行成功,如果执行成功了,那就执行当前Handler,如果没有,就不管:

    /**
       * Set a handler for the result. It will get called when it's complete
       */
      public Future<T> setHandler(Handler<AsyncResult<T>> handler) {
        boolean callHandler;
        //防止线程安全问题...
        synchronized (this) {
          this.handler = handler;
          	// 可能会在此刻,去执行setHandler方法
          callHandler = isComplete();
        }
        if (callHandler) {
          handler.handle(this);
        }
        return this;
      }
    

    再看complete方法

    在这里插入图片描述
    就是tryComplete方法:我们完成只需要将结果赋值进去,然后判断当前Handler有没有设置,如果设置了,那就执行,如果没有设置那就直接返回.
    源码如下:

      @Override
      public boolean tryComplete(T result) {
        Handler<AsyncResult<T>> h;
        //线程安全问题
        synchronized (this) {
        //如果已经执行完成,那就直接返回,并抛出异常
          if (succeeded || failed) {
            return false;
          }
          this.result = result;
          succeeded = true;
          	// 可能会在此刻,去执行setHandler方法,下面还没有执行
          h = handler;
        }
        if (h != null) {
          h.handle(this);
        }
        return true;
      }
    

    如果.没有使用synchronized加锁,会造成什么问题?

    在setHandler的时候,如果当设置完成Handler,线程切出去执行complete方法,这时候会执行两次Handler;
    在complete的时候,如果刚把成功状态改为成功,还没有进行Handler的赋值的时候,去执行setHandler,这时候也会执行两次Handler,就会导致线程安全问题.

    世界上所有的不公平都是由于当事人能力不足造成的.
  • 相关阅读:
    简单自定义控件在view下可以运行在传统模式下运行显示空白
    symbian菜单2运行时更换菜单实现右键菜单功能
    得到文件路径信息 TParse
    Symbian菜单:创建一个最简单的菜单
    RFs 目录操作
    作品[RFileRead/WriteStream 练习] for s60 fp2
    对话框的练习
    文件浏览工具s60第二版
    转描述符
    得到驱动器信息
  • 原文地址:https://www.cnblogs.com/javayida/p/13346758.html
Copyright © 2011-2022 走看看