[英]How does a Java virtual thread know when the thread is waiting?
當一個虛擬線程由於同步調用而被阻塞時,它正在讓出,所以調度器會從相關的 Carrier 線程中卸載它。
我想知道,一個虛擬線程如何知道它當前正在等待 state 並且該讓步了?
看來你有一個小小的誤解:當一個虛擬線程因為同步而被阻塞時,它實際上是在屈服,但調度器不會從相關的載體線程中卸載它。 相反,載體線程將被阻塞,屈服。 這是Loom 項目當前的缺點之一,並且有據可查。 該團隊表示他們可能會在未來修復它。
具體來說,在Coming to Java 19: Virtual threads and platform threads by Nicolai Parlog 2022-05 我們讀到:
不幸的是,最初的虛擬線程提案還有一個不完善之處:當虛擬線程執行本地方法或外部 function或者它在同步塊或方法內執行代碼時,虛擬線程將被固定到其載體線程。 固定線程不會在原本應該卸載的情況下卸載。
(強調我的。)
在同一篇文章的下方,我們讀到:
[...] 同步的一個很好的替代方法是 ReentrantLock。
請注意,我在許多其他官方信息來源中閱讀了相同的內容,而不僅僅是從上面的博客文章中。
這意味着至少現在,如果你想避免阻塞承載線程,你必須避免使用synchronized
關鍵字; 相反,您必須使用ReentrantLock
或其他一些運行時庫 class 來阻止在屈服時等待某些事情發生,例如CountdownLatch
等。
因此,要回答您的問題“Java 虛擬線程如何知道線程何時等待?” 答案是在 Java 19 中修改了所有提供塊等待同時讓出的類(甚至是Thread
的Sleep()
方法),以便它們現在與虛擬線程機制精確協作,以便允許從載體上卸載線。
在代碼的適當位置,檢測到阻塞。 例如
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);
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.