有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java vert。x射线与生物线程

最近,我开始学习reactiveevent-driven、非阻塞Java框架,有一个吸引了我的眼球——vert.x

我想同样的问题可能也适用于akka(Play framework),因为他们的理念或目标是相同的,即减少线程数量,从而提高应用程序的可伸缩性

vert.x表明它所消耗的线程数与CPU内核数相等,但也要记住,有时您必须执行阻塞操作,因此它鼓励开发人员在单独的工作线程上执行阻塞操作(垂直于vert.x的工作者)

这就是我们要问的问题:

  • 如果我要在一个新的独立服务器上执行阻塞IO操作 线程,这意味着执行阻塞操作的每个用户都有 一个新线程,因此线程数再次等于 经典阻塞线程模型中的用户数

一个真实的例子是JDBC查询——如果1000个并发用户通过JDBC查询SQL数据库,那么每个用户都会为该阻塞操作生成自己的工作线程。在我看来,与经典的阻塞线程模型相比,没有线程备用、改进的可伸缩性或RAM备用。我一定错过了什么。。。还是不?提前谢谢你的回答


共 (4) 个答案

  1. # 1 楼答案

    如前所述,您应该使用连接池,但是如果您对数据库访问感兴趣,而不是对JDBC感兴趣,您可以查看异步db驱动程序,例如:

    这些驱动程序依赖于netty,因此其所有IO操作都是非阻塞的,这意味着您不需要有工作线程池。线程更少意味着操作系统级别的上下文切换更少,从而带来更好的性能

    遗憾的是,这些驱动程序并不多(我只知道MySQL和PostgreSQL),所以如果你被迫使用其他RDBMS,你可能就没那么幸运了

  2. # 2 楼答案

    正如其他人所建议的,请查看mysql和postgres的异步驱动程序,它们都有一个专门为vert设计的客户端。x、 这两个数据库涵盖了RDMS的大多数用例

    另一个非阻塞选项是MongoDB,它有一个定制的非阻塞顶点。x客户。很好用,但当然不是SQL

  3. # 3 楼答案

    在一个SQL数据库中产生1000个并发线程是没有意义的——仅仅因为典型的数据库不能承受这么多并发连接,典型的数量是10-15。解决方案是组织一个特殊的线程池,每个线程都有一个开放的连接,并为访问数据库的任务提供服务。任务被提交到一个公共阻塞队列,工作线程以循环的形式从该队列中读取。任务是

    interface DBRunnable {
      public void run(Connection conn);
    }
    

    工作线程将其连接传递到任务:

    public void run() {
      Connection conn = DriverManager.getConnection(...);
      while (true) {
         DBRunnable task=queue.take();
         task.run(conn);
      }
    }
    
  4. # 4 楼答案

    维特。x建议在机器上运行线程,而不是用户

    他们说的是,如果你有16个可用的CPU核,并且有16个准备工作的线程,那么如果你在其中一个线程上运行阻塞操作,最多只有15个线程仍然工作,因此只有15个CPU核实际工作。你的一个核心正在等待

    因此,为了防止有一个空闲内核,他们建议您再创建一个线程,并将阻塞任务交给它,这样您仍然有16个线程在16个CPU内核上工作

    阻塞线程的数量其实并不重要(只要不是太大……)因为它们实际上不会消耗你很多的CPU能量

    它不同于通常的阻塞模型,因为您隔离了不需要太多资源的阻塞操作。剩下的就是在工作线程之间共享剩余的事件驱动操作