Java 的 Spring Boot 与 Python 的 FastApi:线程

Alb*_*iks 3 python java multithreading fastapi project-loom

我是一名 Java Spring boot 开发人员,我开发 3 层 CRUD 应用程序。我和一个似乎对这个主题很了解的人交谈过,但我没有得到他的联系方式。他提倡使用 Python 的 FastApi,因为它的水平扩展性比 Spring boot 更好。他提到的原因之一是FastApi是单线程的。当线程遇到数据库查找(或其他可以异步完成的工作)时,它会选择其他工作,以便稍后在数据库结果传入时返回到当前工作。在 Java 中,当有许多请求待处理时,线程池可能会耗尽。

我不能百分百理解这个推理。让我扮演魔鬼代言人。当Python程序遇到异步调用时,它必须以某种方式将程序指针存储在某个地方,以记住稍后需要在哪里继续。我知道存储程序指针的地方根本不是线程,但我必须给它起个名字,所以我们称它为“逻辑线程”。在 Python 中,您可以有许多正在等待的逻辑线程。在 Java 中,您可以拥有一个线程池,其中有许多正在等待的实际线程。对我来说,唯一的区别似乎是 Java 的线程是在操作系统级别管理的,而 Python 的“逻辑线程”是由 Python 或 FastApi 管理的。为什么在线程池中等待的实际线程比等待的逻辑线程要昂贵得多?如果我的大多数线程都在等待,为什么我不能增加线程池大小以避免耗尽?

Alb*_*iks 7

该问题中的 Java 线程问题已由 Loom 项目解决,该项目现已包含在 Jdk21 中。这里有很好的解释https://www.baeldung.com/openjdk-project-loom

目前,Java 依赖操作系统实现来实现[线程]的延续和[线程]的调度程序。

现在,为了暂停延续,需要存储整个调用堆栈。同样,在恢复时检索调用堆栈。由于延续的操作系统实现包括本机调用堆栈以及 Java 的调用堆栈,因此会产生很大的占用空间。

然而,一个更大的问题是操作系统调度程序的使用。由于调度程序在内核模式下运行,因此线程之间没有区别。它以相同的方式处理每个 CPU 请求。(...) 例如,考虑一个应用程序线程,它对请求执行某些操作,然后将数据传递到另一个线程以进行进一步处理。在这里,最好将这两个线程调度在同一个 CPU 上。但由于 [OS] 调度程序对于请求 CPU 的线程是不可知的,因此这是无法保证的。

问题实际上归结为为什么操作系统线程被认为是昂贵的?