S是由JDK开发人员推荐的,虚拟线程永远不应该被池化,因为创建和销毁它们真的很便宜.我对合用这个概念有点困惑,因为合用通常意味着两件事:

  1. 这些资源应该得到重新利用
  2. 这些资源在发布之前将有一个很长的生命周期

我理解JDK开发人员希望我们永远不要重用虚拟线程,而生命周期问题让我感到困惑,因为如果存在与应用程序本身一样具有生命周期的多个虚拟线程,这听起来可能像是没有重用的池化.

那么,虚拟线程是应该迅速消亡,还是应该有一个短的有限生命周期,或者多个虚拟线程被阻塞,偶尔被唤醒来处理一些任务,并且具有非常长的生命周期,这是可以的吗?

推荐答案

tl;dr

Select 平台线程而不是虚拟线程的原因不是因为任务的生存期有多长,而是(A)如果任务阻塞很少,或者(B)如果任务有synchronized个长时间运行的代码.否则,最好使用虚拟线程.

Details

我怀疑你想得太多了.情况并不真的那么复杂.

在JAVA 21和更高版本的…中

定义您想要以RunnableCallable运行的任何任务.

如果您不关心任务是否并发运行,则通过execute方法将其传递给Executor实例.

如果您确实希望该任务并发运行,请通过submitinvoke…方法传递给ExecutorService.

如果任务涉及阻塞,则使用Executor服务,该服务 for each 任务分配一个新的virtual thread."新的"意味着一个新的、干净的、最小的堆栈,并且没有预先存在的ThreadLocal个对象."阻塞"意味着等待一些事情,这样线程就不能做任何进一步的工作;基本上是任何I/O,如日志(log)记录、文件读/写、对数据库的调用和网络流量.虚拟线程非常"便宜",这意味着创建速度快、内存效率高、CPU效率高.

换句话说,虚拟线程类似于facial tissues:无论何时需要,都可以获取一个新的线程,使用它,然后进行处理.

如果您的任务涉及标记为synchronized的长时间运行的代码,请将synchronized替换为ReentrantLock,或者使用平台线程运行它,如下所述.

如果您的任务(A)不涉及阻塞(受CPU限制,例如视频编码),或者(B)调用本机代码(JNIJEP 454),则不要使用虚拟线程.将这样的任务提交给由平台线程支持的执行器服务(S).如果担心计算机负担过重,请使用由有限数量的线程池支持的Executor服务.

平台线程是"昂贵的".因此,如果您的任务满足上述条件,则最好使用虚拟线程.虚拟线程中的任务可能会短暂运行,也可能会运行很长时间,甚至整个应用程序的持续时间.

在使用池化线程时,请注意清除ThreadLocal个对象,以避免被该线程中的后续任务意外使用.

始终在结束应用程序之前关闭Executor服务.否则,支持线程可能会无限期运行,就像僵尸🧟‍♂️一样.要么使用Try-With-Resources语法自动关闭,要么使用ExecutorService个Javadoc中给出的样板代码.

仅供参考,虚拟线程实际上在JVM自动管理的池中的平台线程上运行您的任务.

要了解更多信息,请阅读上面链接的JEP.请看Ron Pressler、Alan Bateman和José Paumard的演讲.

Java相关问答推荐

Android Studio—java—在onBindViewHolder中,将断点和空白添加到BackclerView中

如何在访问完所有文件后加入所有线程?

相同的Java SerializedLambda为implMethodKind返回不同的结果

如何让DTO接受空字符串字段,但如果它们不为空,则应用JPA验证?

对于亚洲/香港,使用ResolverStyle.STRICT的LocalDate.parse返回意外结果

使用UTC时区将startDatetime转换为本地时间

如何在Application.yaml中连接字符串?

从ActiveMQ Classic迁移到ActiveMQ Artemis需要进行哪些客户端更改?

如何从日志(log)行中删除包名称?

如何在构建Gradle项目时排除com.google.guava依赖项的一个变体

虚拟线程应该很快消亡吗?

是否在settings.xml中使用条件Maven镜像?

如何在EL处理器中定义带有命名空间的变量?

找出承载Cargo 的最小成本

具有多个模式的DateTimeForMatter的LocalDate.parse失败

Oracle中从JSON中提取和插入数据

无法使用Open WebStart Java 8运行jnlp

在权限列表中找不到我的应用程序

rest api服务 spring 启动中出现IllegalFormatConversionException

对于 Hangman 游戏,索引 0 超出长度 0 的范围