我正在调查Project Loom的工作原理以及它能为我的公司带来什么样的好处。
因此,我了解到对于标准的基于servlet的后端,总是有一个线程池执行业务逻辑,一旦线程由于IO而被阻塞,它就无法执行任何操作,只能等待。假设我有一个后端应用程序,其中只有一个端点,这个端点背后的业务逻辑是使用JDBC读取一些数据,它内部使用InputStream,而InputStream又会使用阻塞系统调用(在Linux中为read())。因此,如果有200个用户到达此端点,则需要创建200个线程,每个线程都在等待IO。
现在假设我将线程池切换为使用虚拟线程。根据Ben Evans在文章Going inside Java’s Project Loom and virtual threads中的说法:
相反,虚拟线程在进行阻塞调用(如I/O)时会自动放弃(或屈服)其载体线程。
据我所知,如果我拥有与CPU核心数量相同的OS线程数量和不受限制的虚拟线程数量,则所有OS线程仍将等待IO,Executor服务将无法为虚拟线程分配新的工作,因为没有可用的线程来执行它。这与常规线程有何不同,至少对于OS线程,我可以将其扩展到数千个以增加吞吐量。或者我误解了Loom的用例吗?谢谢。
附加信息
我刚刚阅读了这封mailing list:
虚拟线程喜欢阻塞I/O。如果线程需要在套接字读取中阻塞,则会释放底层内核线程以进行其他工作
我不确定我是否理解了它,如果线程进行像Socket read这样的阻塞调用,操作系统没有办法释放该线程,因为为此内核具有非阻塞syscall,例如epoll,它不会阻塞线程并立即返回一些可用数据的文件描述符列表。上面的引文是否意味着,在幕后,JVM将替换由虚拟线程调用的阻塞read
为非阻塞epoll
?