首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Java的Spring与Python的FastApi:线程

Java的Spring与Python的FastApi:线程
EN

Stack Overflow用户
提问于 2022-07-18 18:03:05
回答 3查看 2.4K关注 0票数 2

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

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

EN

回答 3

Stack Overflow用户

发布于 2022-08-17 23:23:51

这在很大程度上取决于您的线程在做什么。假设您的请求正在调用某个外部端点。大多数情况下,您的java线程(很重)只是什么都不做。有问题吗?视情况而定。在java生态系统中,线程不是即时创建的,这个问题在任何有线程池的框架中都能得到解决。

但是线程堆栈大小仍然占用内存。如果线程池中有1000个线程(或1000个并发请求)等待IO操作,那么您的内存可能很容易超过1GB。

对于这种特殊情况,某些异步/等待抽象可以更好地利用内存。是否所有的任务都会更快地执行则是另一回事了,这取决于许多因素。

所以你真的需要更深一点,你说的是什么尺度?记忆?或所有操作的执行速度(通常也涉及一些cpu)。

java不可忽视的优点是,由线程处理的请求可以并行运行并利用许多处理器,而在python中,这只是,而不是

FastAPI及其异步等待模型易于使用,使开发人员不再使用线程模型,也不考虑并发性。不幸的是,这也意味着如果需要更小的控制。

仅仅在python中调用异步方法并不能提高代码执行的速度。最后,在引擎盖下有一个只运行在一个Cpu上的事件循环。

取决于使用情况,它足够好和有效,或者正好相反。

通常,来自Python生态系统的人会被炒作反对沉重的java,只使用更快/更轻的论点,而没有看到其他的缺点。

这里还有一个链接,可以通过几个框架(在web / rest场景中)与典型的webapp性能比较来戏弄您。

https://www.travisluong.com/fastapi-vs-fastify-vs-spring-boot-vs-gin-benchmark/

票数 2
EN

Stack Overflow用户

发布于 2022-07-18 19:30:04

FastAPI是一个快速的框架,您可以快速(而且容易)在其中创建API后端。老实说,如果您是Java开发人员,我建议您使用Quarkus或其他东西来构建FastAPI,而不是FastAPI。FastAPI是一个非常棒的工具,如果您已经进入了Python生态系统,那么绝对是一个很棒的工具。

当涉及多线程时,Java是“真正的”多线程,因为Python并不是这样。Java线程将同时运行;两个任务可以并将同时执行。在Python中,在一个Python过程中,这几乎是不可能的。这是因为GIL (google it,关于它的工作原理有很多东西)。结果是:即使在Python中使用“真实”线程,代码仍然不是并发执行的,而是串行执行的,其中解释器(对Java的巨大差异)不断地从一个调用堆栈跳到另一个调用堆栈。

至于您所说的“逻辑线程”,我认为您指的是Python的异步能力。这与使用线程(不是真的,但在抽象级别上它们非常相似)是一样的;任务不是并发运行的。只有一个线程经常在任务之间切换。任务将向事件循环(协调任务并决定以哪个顺序执行的对象)返回控制,另一个任务将进一步执行,直到该任务产生控制等。它基本上是与Python中的线程相同的执行模式。

在我看来,将Python框架与Java框架进行比较是很奇怪的。它们既有用又酷,但并不是真正的竞争者。

票数 1
EN

Stack Overflow用户

发布于 2022-07-31 20:17:43

这个问题中的Java线程问题由项目Loom解决,该项目计划在将来的Jdk中包含。在这里很好地解释了https://www.baeldung.com/openjdk-project-loom

目前,

依赖于OS实现来继续线程和调度线程。

现在,为了挂起一个延续,需要存储整个调用堆栈。同样,在恢复时检索调用堆栈。由于继承的OS实现包括本机调用堆栈和Java的调用堆栈,因此造成了很大的占用。

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

这个问题真的可以归结为Why are OS threads considered expensive?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73026698

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档