根据该项目的loom文档,虚拟线程的行为就像普通线程一样,具有几乎零的成本和将阻塞调用转换为非阻塞调用的能力。
如果这是真的,那他们为什么要分开呢?为什么不让它们成为默认的呢?有什么理由不使用它们吗?
发布于 2022-04-23 06:25:36
这里确实有两个问题: 1.为什么虚拟线程不是默认的?2.是否有理由不使用它们。
对于默认情况,Java实际上没有“默认”线程的概念。一旦虚拟线程到达,当您创建一个线程时,您必须指定您想要一个平台线程还是一个虚拟线程。接下来的问题是,为什么我们决定不自动用虚拟线程替换当前的线程(即让new Thread()
创建一个虚拟线程)。答案很简单:它根本没有帮助,而且很可能是相当有害的。这不会有帮助,因为虚拟线程的优势来自于创建大量线程的能力。如果您的应用程序今天创建了N个线程,那么将这些N个线程转换为虚拟线程不会有什么好处。虚拟线程的扩展优势只有在应用程序创建1000 N线程时才会发挥作用,这意味着无论如何都需要对其进行更改(例如,将Executors.newFixedThreadPool
替换为Executors.newVirtualThreadPerTaskExector
)。这可能是有害的,因为虽然虚拟线程的语义与平台线程几乎相同,但它们并不完全向后兼容(详见9月425 )。
至于何时不使用虚拟线程的问题,有一些明显的例子。例如,当您的线程大量地与本机代码交互时,本机代码对虚拟线程一无所知,或者当您依赖于对虚拟线程已经更改的一些细节时,比如子类Thread
的能力。其他情况则不太清楚。例如,与CPU内核相比,CPU绑定操作不会受益于更多的线程,因此它们不会从大量的虚拟线程中受益,但这并不意味着它们会受到损害。我们还没有准备好说默认情况下用户应该选择虚拟线程,但是我们很有可能做到这一点,因为我们了解了人们如何使用它们的更多信息。
发布于 2022-04-20 15:47:07
请注意,织机项目正在进行积极的试验开发。事情可能会改变。
无缺省值
你问:
为什么不让它们成为默认的呢?
在现代Java中,我们通常不直接寻址线程。相反,我们使用的是几年前在Java 5中添加的Executors框架。
特别是,在大多数情况下,Java程序员使用Executors
实用程序类来生成ExecutorService
。该执行器服务由各种线程工厂或线程池支持。
例如,如果您想一个接一个地序列化一个任务,我们将使用一个单线程支持的executor服务。
ExecutorService executorService = Executors.newSingleThreadExecutor() ;
如果浏览Executors
类Javadoc,您将看到各种各样的选项。其中没有一个是“默认”的。程序员选择一个以适应她特殊情况的需要。
有了工程织机,我们至少还有一个这样的选择可供选择。在Java的预览构建中,调用新的Executors.newVirtualThreadPerTaskExecutor()
以获得由虚拟线程支持的执行器服务。去疯狂吧,把一百万项任务扔给它。
ExecutorService executorService = Executors.newVirtualThreadPerTaskExecutor() ;
你问:
他们为什么要把事情分开?
Java团队的首要任务之一是向后兼容性:现有的应用程序应该能够毫无意外地运行。
虚拟线程的行为和性能配置文件与平台线程非常不同。因此,我不希望看到Java团队将虚拟线程改造到Java的现有特性上。他们可能会选择这样做,但前提是必须绝对肯定,现有应用程序的行为不会出现任何有害影响。
何时选择或避免虚拟线程
你问:
有什么理由不使用它们吗?
是的,当然。原因有二:
CPU绑定任务
虚拟线程的全部目的是保持“真实”线程、平台主机-OS线程的忙碌。当一个虚拟线程阻塞,例如等待存储I/O或等待网络I/O时,虚拟线程从主机线程“卸载”,而另一个虚拟线程被“挂载”在主机线程上以完成某些执行。
因此,如果任务的代码没有阻塞,就不要使用虚拟线程。但是这种代码是很少见的。大多数应用程序中的大多数任务通常都在等待用户、存储、网络、附加设备等。一个罕见的任务可能不会被阻止的例子是CPU约束,比如视频编码/解码、科学数据分析或某种密集的数字处理。这些任务应该直接分配给平台线程,而不是虚拟线程。
节流
避免使用虚拟线程的另一个原因是现有代码依赖于平台线程的限制或瓶颈来限制应用程序对其他资源的使用。例如,如果一个数据库服务器仅限于10个同时连接,那么已经编写了一些应用程序来使用仅由8个或9个线程支持的executor服务。这种现有的代码不应该盲目地切换到虚拟线程。
当然,这样的代码不是最优的。如果使用了显式限制/节流机制,这样的代码库将更好、更清晰、更明显。
如果程序员想要在避免耗尽/重载其他有限资源的同时拥有成千上万甚至数百万的同步虚拟线程,则需要使用显式节流机制。
Java长期以来一直提供这样的节流机制。考虑到依赖于有限数量平台线程的限制/瓶颈的简单性/容易性,它们并不总是被使用。
我不是这方面的专家。所以要依靠那些专家。要获得详细信息和见解,请务必阅读这些文章,并观看罗恩·普雷斯勒、艾伦·贝特曼或项目织机团队的其他成员的演示和采访。
发布于 2022-09-29 09:38:58
我们先从
为什么不让它们成为默认的呢?
虚拟线程封装在平台线程上,因此您可能会认为它们是JVM提供的错觉,整个想法是将线程的生命周期设置为 CPU界 操作。
第四层架构有更好的理解.
CPU
操作系统
JVM
带有可执行服务的虚拟线程
虚拟线程优势
虚拟线程使用注意事项
查找有关杰普-425的更多信息
https://stackoverflow.com/questions/71945866
复制相似问题