Vertx,多线程如何工作

Alm*_*zak 6 java multithreading vert.x

在 Vertx 官方文档中,我阅读了以下段落

   If a result can be provided immediately, it will be returned immediately, otherwise you will usually provide a handler to receive events some time later.
Because none of the Vert.x APIs block threads that means you can use Vert.x to handle a lot of concurrency using just a small number of threads.
Run Code Online (Sandbox Code Playgroud)

在关于 Reactor 的文章中:

Vert.x works differently here. Instead of a single event loop, each Vertx instance maintains several event loops. By default we choose the number based on the number of available cores on the machine, but this can be overridden.
Run Code Online (Sandbox Code Playgroud)

据我了解,如果我写错了,请纠正我,Vertx 的工作方式如下:

当我们为阻塞代码提供处理程序时,vertx 将一个线程(不是事件循环)从线程池中放入此代码,该线程等于内核数,例如我有 4 个内核,并且事件循环在每次迭代后检查此线程的状态并且如果它准备好执行与此阻塞代码相关的处理程序,当所有 4 个内核都忙时,vertx 将任务放入队列以供稍后执行,

那么worker verticle呢,我们有另一个线程池,默认情况下等于20,当我们使用以下方法时:vertx.executeBlocking()我们使用这个池中的线程。

我的理解正确吗?

(PS)根据下面的答案,使用处理程序阻塞代码和使用处理程序阻塞代码但使用执行阻塞没有区别

//jdbc
    connection.execute("insert into test values (1, 'Hello'), (2, 'World')", insert -> {

              // query some data with arguments
              connection.queryWithParams("select * from test where id = ?", new JsonArray().add(2), rs -> {
                if (rs.failed()) {
                  System.err.println("Cannot retrieve the data from the database");
                  rs.cause().printStackTrace();
                  return;
                }
    }
Run Code Online (Sandbox Code Playgroud)

//工作线程

vertx.executeBlocking(e->{},handler->{});
Run Code Online (Sandbox Code Playgroud)

我的理解是否正确,两个代码都在后台使用了工作线程?

Ger*_*cke 7

Vert.x 维护着两个线程池。

一种带有事件循环线程。默认情况下,每个内核有两个事件循环线程。在 4 核机器上,您将有 8 个事件循环线程。每个非阻塞代码都在事件循环上运行。如果部署多个 Verticle,它们通常均匀分布在事件循环线程上。重要的是代码不会被阻塞,否则同一事件循环上的所有其他代码都会被阻塞。

另一个线程池是工作池(默认大小为 20,但这是可配置的,请参阅https://vertx.io/docs/apidocs/io/vertx/core/VertxOptions.html#DEFAULT_WORKER_POOL_SIZE),有点“经典”线程。当您调用executeBlocking这段代码时,它会被分派到工作池的一个线程,因此它不会阻塞事件循环。

当你执行阻塞时,你提供了两个处理程序,一个执行阻塞代码,它在工作线程上运行,另一个 - 接收结果 - 在事件循环(调用者线程,如果你喜欢)上运行

vertx.executeBlocking(fut -> {
  //blocking code, run on the worker thread
  fut.complete("my result");
}, res -> {
  //non blocking code running on the event loop thread
  System.out.println(res.result());
});
Run Code Online (Sandbox Code Playgroud)

关于您添加的问题,您在这里使用 Vert.x JDBC 客户端,它在后台运行工作线程上的阻塞 JDBC 部分,因此您不必处理这个问题。所以,是的,它与在executeBlocking语句中的第一个,blockingHandler 中编写自己的 JDBC 访问代码基本相同。您也可以在 Vert.x JDBC 客户端的代码中看到它:https : //github.com/vert-x3/vertx-jdbc-client/blob/c83138c00390777f3d17ac492f09203e9e92284d/src/main/java/io/vertx/ext /jdbc/impl/actions/AbstractJDBCAction.java#L66