我正在研究Project Loom是如何运作的,以及它能给我的公司带来什么样的好处。
所以我理解动机,对于基于标准 servlet 的后端,总是有一个执行业务逻辑的线程池,一旦线程因为 IO 而被阻塞,它除了等待什么也做不了。因此,假设我有一个具有单个端点的后端应用程序,该端点背后的业务逻辑是使用内部使用 InputStream 的 JDBC 读取一些数据,后者将再次使用阻塞系统调用(在 Linux 中为 read())。所以如果我有 20000 个用户到达这个端点,我需要创建 200 个线程,每个线程等待 IO。
现在假设我将线程池切换为使用虚拟线程。根据 Ben Evans 在Going inside Java's Project Loom and virtual threads一文中的说法:
相反,当进行阻塞调用(例如 I/O)时,虚拟线程会自动放弃(或让出)它们的载体线程。
据我了解,如果我的操作系统线程数量等于 CPU 内核数量和无限数量的虚拟线程,所有操作系统线程仍将等待 IO,并且执行器服务将无法为虚拟线程分配新工作因为没有可用的线程来执行它。它与常规线程有何不同,至少对于操作系统线程,我可以将其扩展到数千以增加吞吐量。还是我只是误解了 Loom 的用例?提前致谢
添加在
我刚刚阅读了这个邮件列表:
虚拟线程喜欢阻塞 I/O。如果线程需要阻止 Socket 读取,那么这会释放底层内核线程以执行其他工作
我不确定我是否理解它,如果操作系统执行诸如读取之类的阻塞调用,则操作系统无法释放线程,出于这些目的,内核具有非阻塞系统调用,例如 epoll,它不会阻塞线程并立即返回有一些可用数据的文件描述符列表。上面的引用是否暗示在后台,如果调用它的线程是虚拟的,JVM 将用read
非阻塞替换阻塞?epoll