vertx的Future设计

异步痛点

1.回调地狱(CallBack hell) ; 解决方式 Promise 或 Future

2.执行异步后的结果如何回调currentThread ; 解决方式 Context 设计

3.如何处理依赖多异步的result进行逻辑 ; 解决方案 CompositeFuture

JDK的lib库 Callable和Future 问题

Callable任务可以返回结果,返回的结果可以由Future对象取出,但是调用Future.get()会阻塞当前线程

public V get() throws InterruptedException, ExecutionException {
    int s = state;
    if (s <= COMPLETING)
        s = awaitDone(false, 0L);
    return report(s);
}


public V get(long timeout, TimeUnit unit)
    throws InterruptedException, ExecutionException, TimeoutException {
    if (unit == null)
        throw new NullPointerException();
    int s = state;
    if (s <= COMPLETING &&
        (s = awaitDone(true, unit.toNanos(timeout))) <= COMPLETING)
        throw new TimeoutException();
    return report(s);
}

 /**
 * 等待完成,或者中断、超时
 *
 * @param timed 定义了超时则为true
 * @param nanos 等待时间
 */
private int awaitDone(boolean timed, long nanos)
    throws InterruptedException {
    final long deadline = timed ? System.nanoTime() + nanos : 0L;
    WaitNode q = null;
    boolean queued = false;
    //轮询查看FutureTask的状态
    for (;;) {
        if (Thread.interrupted()) {//线程中断
            removeWaiter(q);
            throw new InterruptedException();
        }

        int s = state;
        if (s > COMPLETING) {//完成或取消状态
            if (q != null)
                q.thread = null;
            return s;
        }
        else if (s == COMPLETING)//正在set result,Thread “运行状态”进入到“就绪状态”
            Thread.yield();
        else if (q == null)
            q = new WaitNode();
        else if (!queued)
            queued = UNSAFE.compareAndSwapObject(this, waitersOffset,
                                                 q.next = waiters, q);
        else if (timed) {
            nanos = deadline - System.nanoTime();
            if (nanos <= 0L) {
                removeWaiter(q);
                return state;
            }
            LockSupport.parkNanos(this, nanos);
        }
        else
            LockSupport.park(this);
    }
}

 

vertx的Future设计

1. Future通过事件注册(EventHandler)回调方式,来解决Thread阻塞问题.

UML图:

image    

Futrue instances 采用FutureFactory生产,基于 SPI 机制:

public class FutureFactoryImpl implements FutureFactory {

  private static final SucceededFuture EMPTY = new SucceededFuture<>(null);

  /**
    * 创建FutureImpl 实例
    */
  public <T> Future<T> future() {
    return new FutureImpl<>();
  }

  /**
    * 返回一个常量 SucceededFuture 实例
    * result本身为null, 可以减少内存开销
    */
  public <T> Future<T> succeededFuture() {
    @SuppressWarnings("unchecked")
    Future<T> fut = EMPTY;
    return fut;
  }

  /**
    * 创建一个 SucceededFuture 实例
    */
  public <T> Future<T> succeededFuture(T result) {
    return new SucceededFuture<>(result);
  }

  /**
    * 创建一个 FailedFuture 实例
    */
  public <T> Future<T> failedFuture(Throwable t) {
    return new FailedFuture<>(t);
  }

  /**
    * 创建一个 FailedFuture 实例
    */
  public <T> Future<T> failureFuture(String failureMessage) {
    return new FailedFuture<>(failureMessage);
  }
}

 

多异步的result如何组合(并行变串行)

使用的CompositeFuture,来处理多异步结果组合问题:采用计数器(Counters)的方法来解决 wait 问题

image

public class CompositeFutureImpl implements CompositeFuture, Handler<AsyncResult<CompositeFuture>> {

  private final Future[] results;//定义数组
  
  private int count;//计数器
  
  private boolean completed;//是否完成
  
  private Throwable cause;//错误原因
  
  private Handler<AsyncResult<CompositeFuture>> handler;// 回调 eventHandler
  
  public static CompositeFuture all(Future<?>... results) {
    CompositeFutureImpl composite = new CompositeFutureImpl(results);//创建实例
    int len = results.length; //获取 futures数组长度
    for (int i = 0; i < len; i++) {
      results[i].setHandler(ar -> {
        Handler<AsyncResult<CompositeFuture>> handler = null;
        if (ar.succeeded()) {
          synchronized (composite) { //添加内存屏障,防止并发问题
            composite.count++; 
            if (!composite.isComplete() && composite.count == len) {//所有future成功
              handler = composite.setCompleted(null);
            }
          }
        } else {
          synchronized (composite) {//添加内存屏障,防止并发问题
            if (!composite.isComplete()) {//任何一个失败就失败
              handler = composite.setCompleted(ar.cause());
            }
          }
        }
        if (handler != null) {//执行回调EventHandler
          handler.handle(composite);
        }
      });
    }
    if (len == 0) {//判断临界点
      composite.setCompleted(null);
    }
    return composite;
    }
}

public static CompositeFuture any(Future<?>... results) {
    CompositeFutureImpl composite = new CompositeFutureImpl(results);
    int len = results.length;
    for (int i = 0;i < len;i++) {
      results[i].setHandler(ar -> {
        Handler<AsyncResult<CompositeFuture>> handler = null;
        if (ar.succeeded()) {
          synchronized (composite) {
            if (!composite.isComplete()) {//任何一个成功
              handler = composite.setCompleted(null);
            }
          }
        } else {
          synchronized (composite) {
            composite.count++;
            if (!composite.isComplete() && composite.count == len) {//所有future失败
              handler = composite.setCompleted(ar.cause());
            }
          }
        }
        if (handler != null) {//执行回调EventHandler
          handler.handle(composite);
        }
      });
    }
    if (results.length == 0) {//判断临界点
      composite.setCompleted(null);
    }
    return composite;
}

private  static CompositeFuture join(Function<CompositeFuture, Throwable> pred, Future<?>... results) {
    CompositeFutureImpl composite = new CompositeFutureImpl(results);
    int len = results.length;
    for (int i = 0; i < len; i++) {
      results[i].setHandler(ar -> {
        Handler<AsyncResult<CompositeFuture>> handler = null;
        synchronized (composite) {
          composite.count++;
          if (!composite.isComplete() && composite.count == len) {//处理所有不管失败还是成功
            // Take decision here
            Throwable failure = pred.apply(composite);
            handler = composite.setCompleted(failure);
          }
        }
        if (handler != null) {
          handler.handle(composite);
        }
      });
    }
    if (len == 0) {//{//判断临界点
      composite.setCompleted(null);
    }
    return composite;
}

/**
  * 根据下标返回结果
  * /
public <T> T resultAt(int index) {
    return this.<T>future(index).result();
}
 

 

public interface CompositeFuture extends Future<CompositeFuture> {
    /**
      * 返回list Future.result()
      */
    default <T> List<T> list() {
        int size = size();
        ArrayList<T> list = new ArrayList<>(size);
        for (int index = 0;index < size;index++) {
          list.add(resultAt(index));
        }
        return list;
    }
}

 

转载于:https://www.cnblogs.com/cmfa/p/10578985.html

<think>好的,我现在需要回答用户关于Vert.x的问题,用户想了解它的定义、用途、功能以及特点。首先,我需要回忆一下Vert.x的相关知识,并结合提供的引用内容来组织答案。 首先,Vert.x的定义。根据引用3,Vert.x被描述为一个响应式、非阻塞的框架,提供简洁的API,支持多种语言。所以应该先明确它是一个工具库,用于构建高性能、分布式的应用。同时,引用2提到它支持多语言绑定,比如JavaScript、Python等,这也是一个关键点。 接下来是用途。根据引用4,Vert.x适用于高并发场景,比如实时Web应用、微服务架构等。需要强调它在处理大量并发连接时的优势,以及模块化部署的特点,如引用5中的Verticle独立部署。 功能方面,引用3提到Vert.x提供了数据库操作、Redis、Web客户端等常用工具,说明它拥有丰富的内置模块。另外,引用5中的Verticle部署机制也是一个重要功能,支持模块化开发和管理。引用1中的配置VertxOptions设置线程池大小,说明Vert.x的可配置性也是其功能之一。 特点部分,响应式和非阻塞I/O肯定是核心,多语言支持(引用2)、轻量级(对比Spring,引用3)、高扩展性(引用4的生态体系)都需要涵盖。另外,事件驱动模型和异步处理也是关键特点。 需要注意引用内容的正确使用,比如在提到配置时引用1,多语言绑定引用2,对比Spring引用3,生态体系引用4,模块化部署引用5。同时,按照用户要求,回答结构要清晰,分点说明,并且生成相关问题。 最后,检查是否符合系统级指令,比如数学公式是否正确(虽然这里可能用不上),使用中文,引用标识是否正确添加。确保每个主要点后面都有对应的引用标注,例如在说明多语言支持时引用[^2],在模块化部署时引用[^5]等。 总结下来,结构大致分为定义、用途、功能、特点四个部分,每个部分结合引用内容展开,最后生成相关问题。需要确保语言流畅,避免技术术语过于复杂,让用户容易理解。</think>### Vert.x的定义与核心概念 Vert.x是一个**响应式、事件驱动、非阻塞**的应用框架,用于构建高性能、分布式、可扩展的现代应用程序。它基于JVM(Java虚拟机),但支持多种编程语言(如Java、Kotlin、JavaScript、Python等),通过异步和非阻塞I/O模型处理高并发场景[^3][^4]。 --- ### 主要用途 1. **高并发服务**:例如实时Web应用、API网关、物联网(IoT)消息处理。 2. **微服务架构**:支持模块化部署(通过Verticle),适合构建轻量级微服务[^5]。 3. **事件驱动系统**:如消息队列、实时数据处理等。 4. **跨语言集成**:通过多语言绑定简化异构系统开发。 --- ### 核心功能 1. **非阻塞I/O**:通过事件循环(Event Loop)高效处理请求,避免线程阻塞。 2. **多语言支持**:提供Java、Python、Ruby等语言的API绑定。 3. **内置模块**: - 数据库客户端(MySQL、PostgreSQL等)。 - Web客户端与HTTP服务器。 - 分布式事件总线(Event Bus)。 4. **Verticle模型**:将应用拆分为独立模块(Verticle),支持隔离部署和水平扩展。 5. **灵活配置**:例如通过`VertxOptions`调整线程池大小[^1]。 --- ### 核心特点 1. **响应式设计**:遵循响应式系统原则(弹性、弹性、消息驱动)。 2. **轻量级**:与Spring等框架相比,依赖更少,启动更快[^3]。 3. **高扩展性**:通过Verticle和事件总线轻松实现分布式架构。 4. **异步编程模型**:支持`Future/Promise`、回调函数等异步模式。 5. **生态完善**:提供Web、数据访问、安全等扩展模块。 --- ### 示例代码(Verticle部署) ```java // 定义一个Verticle public class MyVerticle extends AbstractVerticle { @Override public void start() { vertx.createHttpServer() .requestHandler(req -> req.response().end("Hello Vert.x!")) .listen(8080); } } // 部署Verticle Vertx vertx = Vertx.vertx(); vertx.deployVerticle(new MyVerticle()); ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值