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

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

#1楼 票数:0 已采纳

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

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

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

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

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

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

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

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

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

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

  ask by matanster translate from so

未解决问题?本站智能推荐:

2回复

Akka的轻量级线程

我最近读到了Quasar ,它为JVM提供了“轻量级”/类似Go的“用户模式”线程(它还有一个像Akka一样的Erlang启发的Actor系统,但这不是主要问题) 例如: 据我所知,上面的代码没有产生任何JVM /内核线程,所有这些都是在用户模式线程中完成的(或者他们声称)这应该更
1回复

限制JVM可以使用的活动线程/核心数

这个问题已经在这里有了答案: 是否可以强制现有的Java应用程序使用不超过x个内核? 2个答案 我在Scala中有一段代码(使用Java执行上下文)产生了很多线程。 我也有一个8核CPU。 当该过程运行时,它将耗尽计算机所拥有的全部汁液,而我无能为力。
3回复

除了Scala之外,还可以在JVM上运行的替代多线程优化语言?

我正在严格地在多核桌面应用程序编程方面寻找Scala的替代产品或竞争对手。 无论使用CPU还是GPU内核(ScalaCL),我都想利用所有可能的多线程性能。 Scala绝对是一个不错的选择,但是我想知道我可以追求哪些其他选择。 在JVM上运行是我需要的关键。
3回复

JVM:是否可以操纵框架堆栈?

假设我需要在同一线程中执行N个任务。 这些任务有时可能需要外部存储中的某些值。 我事先不知道哪个任务可能需要这样的值以及什么时候。 一次性读取M个值要快于向外部存储的M个查询中相同的M个值。 请注意, 我不能期望任务本身的合作,可以将它们视为java.lang.Runnable对象
2回复

Java vs Scala Threads - 在JVM的封面下

在尝试比较Java和Scala中实现的同一个简单问题的“执行特性”时,我发现Java版本中的线程类在名为Thread-x的线程上运行,而Scala actor在名称类似的线程上运行ForkJoinPool-x-worker-y 。 非线程Java类和非actor actor Scala类始终在
3回复

实施事件驱动的轻量级线程

受Akka和Quasar之类的图书馆的启发,我开始想知道它们实际上是如何“在后台”工作的。 我知道这很可能非常复杂,并且它们彼此之间的工作方式完全不同。 我仍然想学习如何使用Java 8实现(最多)我自己的“事件驱动的轻量级线程”的非常基本的版本。 我对Akka作为一个库非常熟悉,
1回复

如何检查哪个线程持有显示器?

我有一个性能问题(在使用并行集合和期货的复杂 Scala 代码中)。 我已经使用 JFR 检查了更多细节,我可以看到问题表现为一个线程在等待监视器对象(该线程似乎在java.util.concurrent.ForkJoinTask#internalWait通过调用ForkJoinTask的wait方
1回复

线程调度程序是 JVM 的一部分还是 OS 的一部分? [复制]

这个问题在这里已经有了答案: JVM 线程调度程序如何控制多处理器的线程? (3 个回答) 去年关闭。