2017-08-29 55 views
1

正常情況下,當一個任務被提交給一個線程池(我們假設一個Fork-Join池)時,它佔用了它運行的線程直到它完成。因此,如果任務必須等待,例如完成Future,則它將保留該線程。如果許多此類任務正在等待,這可能是不可取的;然後,許多線程被擱置。這不僅會消耗大量內存,而且最糟糕的是,您可能會達到極限,並且無法再創建任何新線程導致死鎖(例如,在我的macbook上,我無法在JVM中創建超過幾千個線程)。Java/Scala ThreadPool:如何在等待時釋放線程?

有人可能會爭辯說,可以通過更改我的程序來避免這種情況,但很可能是因爲我的程序不易讀和更長的代價才能解決問題。


我的問題是是否有可能以某種方式來實現方法release釋放線程使得線程可以被用於拾取從隊列中的另一任務,並安排的休息方法作爲一項新任務? 所以我希望這樣做可能使用反射,但無法找出如何。

假設 在我的情況下,你只能假設Runnable s(因此沒有返回值)。也不需要擔心調用堆棧,即釋放直接發生在構成提交給線程池的任務的方法中。

一個簡單的用法是這樣的:

// some code 
while (! future.isDone()){ 
    return; 
} 
// continue with the logic 

回答

0

Java線程映射一來一往原生線程,你問什麼是不可能的。實際上,您正在尋求類似continuation或green threads/coroutines的內容。這種方法有一些侷限性,目前它們不是很受歡迎。 JVM上存在的一個示例是Kotlin coroutines

在純Java中,您可以使代碼的這部分代碼異步,並使用CompletableFuture.thenAccept或其他可組合方法在原始未來完成後安排進一步的處理。類似於斯卡拉擁有更豐富的期貨和承諾庫。另一種可能性是分割你的邏輯並將部分代碼作爲任務提交給Executor實例。

+0

事實上,它就像延續。讓我檢查一下Kotlin,看看如何解決我的問題。 – Mahdi