会议上提到,由于固定虚拟线程,虚拟线程synchronized 可能会出现问题,如果这是一个问题,那么使用可以解决问题。

我不明白为什么 Lock 在虚拟线程环境中会比 syncronized 更好。我猜想可能是导致相同固定的原因。不是吗?如果不是 – 为什么?

8

  • 1
    如果被锁定,synchronized 关键字不会产生平台线程,而其他实现可能会。


    – 

  • 原则上,没有理由认为synchronized应该与 的最简单用例有任何不同ReentrantLock。无论详细答案是什么,它都将是一些任意设计决策的结果——可能是很久以前做出的决定。不管是什么,除了时间和金钱,没有什么能阻止他们修复它。


    – 

  • 3
    你过度使用粗体字,这让人很烦。你这样面对面跟人说话吗?你每说一句话都要大喊几句吗?


    – 

  • 可能重复答案虽然很旧,但有趣的是,由于其编辑,它保留了对虚拟线程的引用。


    – 


  • 3
    原因很简单,支持对象监视器是较低级别的 VM 更改,而 ReentrantLock 则是一个较小的调整。因此,它可能会降级到以后的里程碑,以专注于其他核心基础知识。最近的已添加支持,因此这个问题将在以后的 JDK 版本中消失。


    – 


最佳答案
1

)适用于涉及的任务,即不受任务。阻塞任务包括执行文件 I/O、日志记录、网络调用、数据库访问等的任务。

当虚拟线程被阻塞时,可以快速将其切换为另一个虚拟线程,以保持忙碌。虚拟线程之间的这种快速切换使它们具有如此高的性能。

Java 21 和 Java 22 中的当前实现存在一个限制。当synchronized块内的代码正在运行时,Java 无法检测该代码是否被阻止。该任务无法切换为另一个虚拟线程来执行。因此,被阻止的代码只能在那里等待,因此该核心无法执行任何有用的工作。

这种虚拟线程卡住的问题称为固定。被阻塞的虚拟线程被固定到该核心上的主机平台线程。固定违背了使用虚拟线程的目的。

短暂固定不是问题。例如,快速检查受保护的保护变量。但长时间运行的固定代码块是一个问题。这种长时间运行的代码块synchronized应该 (a) 不在虚拟线程上运行,或者 (b) 应该重写为使用而不是使用synchronized

团队正在继续研究这个问题。。因此,Java 的未来版本可能会摆脱这一限制。

顺便说一句,类似的固定情况是本机代码。使用调用长时间运行的本机代码的 Java 代码不应虚拟线程中使用。

理解虚拟线程:

  • 研究
  • 观看 Ron Pressler、Alan Bateman 和 José Paumard 的视频演示。

3

  • 锁定是否仅在进入同步块后发生?当线程被阻塞并等待同步块监视器空闲时会怎样?


    – 

  • 这并没有回答问题。synchronized 和 reentrant 之间有什么区别?为什么 JVM 可以检测到一个阻塞操作,而另一个却不能?解决方案的链接有点用,但也没有涵盖原始问题。


    – 


  • 2
    @Basilevs 区别在于,其中一个已经实现了该功能(载体线程切换到另一个虚拟线程),但另一个尚未实现。但他们已经在为另一个实现该功能,一旦完成,就不会再有区别了。这个答案中已经说了这么多。


    –