当一个虚拟线程由于同步调用而被阻塞时,它就会产生,所以调度程序将从相关的承运人线程中卸载它。
我想知道,一个虚拟线程如何知道它目前处于等待状态,是时候放弃了?
发布于 2022-11-26 15:20:14
您似乎有一点误解:当一个虚拟线程由于同步而被阻塞时,它实际上是屈服的,但是调度程序不会将它从相关的载波线程中卸载。相反,载体线程将被阻塞,屈服。这是当前的缺点之一,并且有很好的文档。小组说他们可能会在未来修复它。
具体来说,在NicolaiParlog2022-05的中,我们读到:
不幸的是,初始虚拟线程建议中还有一个缺陷:当虚拟线程执行本机方法或外部函数或在同步块或方法中执行代码时,将将虚拟线程固定在其载体线程上。钉扎的线程在其他情况下不会卸载。
(强调我的)
在同一篇文章中,我们进一步读到:
...同步的一个很好的替代方案是ReentrantLock。
请注意,我在其他一些官方信息来源中读过同样的东西,而不仅仅是从上面的博客文章中读到的。
这意味着,至少在目前,如果您想避免阻塞载体线程,则必须避免使用synchronized关键字;相反,您必须使用一个ReentrantLock或其他运行时库类,该类阻止在生成时等待发生的事情,例如CountdownLatch等。
因此,要回答您的问题“Java虚拟线程如何知道线程何时等待?”答案是,所有在生成时提供块等待的类(甚至是Sleep()方法的Thread)都在Java 19中进行了修改,以便它们现在能够精确地与虚拟线程机制合作,从而允许从载体线程中卸载。
发布于 2022-11-26 14:06:34
在代码中的适当位置,检测到阻塞。例如
public static void parkNanos(Object blocker, long nanos) {
if (nanos > 0) {
Thread t = Thread.currentThread();
setBlocker(t, blocker);
try {
if (t.isVirtual()) {
VirtualThreads.park(nanos);<====
} else {
U.park(false, nanos);
}
} finally {
setBlocker(t, null);
}
}
}https://stackoverflow.com/questions/74581601
复制相似问题