簡體   English   中英

Java 虛擬線程如何知道線程何時等待?

[英]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 中修改了所有提供塊等待同時讓出的類(甚至是ThreadSleep()方法),以便它們現在與虛擬線程機制精確協作,以便允許從載體上卸載線。

在代碼的適當位置,檢測到阻塞。 例如

  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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM