JVM线程管理与OS调度

马坦斯特

据我所知,最常见的JVM并发API之一:期货-至少在scala中实现-依靠用户代码在线程可能等待空闲时放弃线程。在Scala中,通常将其称为“避免阻塞”,开发人员必须在有意义的任何地方实施它。不太有效。

JVM是否具有完全完全固有的功能,可以防止JVM将线程的上下文切换到新任务(当线程处于空闲状态时)(由操作系统进程调度程序实现)?

the8472

JVM是否具有完全完全固有的功能,可以防止JVM将线程的上下文切换到新任务(当线程处于空闲状态时)(由操作系统进程调度程序实现)?

大多数情况下,这种切换必须合作完成。每个单一的阻塞方法都必须以某种方式包装或重新实现,以使该任务一旦完成就可以恢复。毕竟,不再有本机线程等待阻塞操作的完成。

尽管原则上可以针对JVM内部阻塞方法完成此操作,但考虑通过JNI执行的任意本机代码,JVM不会知道如何对这些本机线程进行堆栈切换,但它们毕竟卡在了本机代码中。

您可能想看一下类星体,据我了解类星体为某些JDK内部方法实现了此类包装程序或等效类,例如sleeppark/ unpark,基于通道的IO和其他允许它们的光纤(以及期货)的方法。在这些光纤上运行)以在它们等待完成时准确地执行那种用户模式上下文切换。

编辑:仅JNI便已足以将用户模式任务切换限制为机会优化,当本机代码阻塞线程时,可能必须回落到旋转其他本机线程。

但这不是唯一的问题,例如,在linux上,真正的异步文件IO操作需要文件系统和内核支持(请参阅AIO上的SO问题),但并不是所有人都提供的。如果没有提供,则必须使用其他阻塞的IO线程进行仿真,从而重新引入了我们首先要避免的所有开销。最好只是阻塞线程池本身并增加其他线程,至少我们将避免这种方式的线程间通信。

内存映射文件也可能会阻塞线程,并由于页面错误而迫使OS调度程序挂起线程,我不知道与虚拟内存系统合作避免这种情况的方法。

更不用说VM上的所有阻塞调用都必须使用OS提供的异步等效项来重新实现。甚至错过一个,您的线程就会被阻塞。如果线程被阻塞,则线程池将需要自动增长功能,我们将回到正题。

最后但并非最不重要的一点是,在某些情况下,可能希望使用每个文件描述符一个线程的IO。确保用户模式切换所需的普遍更改可能会破坏这些更改。

因此总而言之,有时可以进行用户模式切换但是JVM无法对此做出硬性保证,因此无论如何它都必须实现所有本机线程处理,并且程序员在考虑到执行这些未来的线程池的假设的前提下,至少在某种程度上可以协同工作。有些情况可以消除,但并非所有情况都可以消除。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章