2015-05-13 15 views
4

這裏是代碼:在Scala的「未來」的ForkJoinPool中,爲什麼工人的ID總是奇數?

import scala.concurrent._ 
import ExecutionContext.Implicits.global 
import scala.concurrent.duration._ 


val is = 1 to 100 toList 
def db = s"${Thread.currentThread}" 
def f(i: Int) = Future { println(db) ; 2 * i } 

val theFuture = Future.traverse(is)(f _) 

Await.result(theFuture, 10.seconds) 

我拼命地跑了很多次,結果是這樣的:

Thread[ForkJoinPool-1-worker-3,5,main] 
Thread[ForkJoinPool-1-worker-3,5,main] 
Thread[ForkJoinPool-1-worker-3,5,main] 
Thread[ForkJoinPool-1-worker-3,5,main] 
Thread[ForkJoinPool-1-worker-3,5,main] 
Thread[ForkJoinPool-1-worker-1,5,main] 
Thread[ForkJoinPool-1-worker-5,5,main] 
Thread[ForkJoinPool-1-worker-7,5,main] 
Thread[ForkJoinPool-1-worker-7,5,main] 
Thread[ForkJoinPool-1-worker-7,5,main] 
Thread[ForkJoinPool-1-worker-7,5,main] 
Thread[ForkJoinPool-1-worker-7,5,main] 
Thread[ForkJoinPool-1-worker-7,5,main] 
Thread[ForkJoinPool-1-worker-7,5,main] 
Thread[ForkJoinPool-1-worker-7,5,main] 
Thread[ForkJoinPool-1-worker-3,5,main] 

模式始終是 「主題[ForkJoinPool-1-工人 - 」 $ { AnOddNumber} 「5,主]」。有沒有人有關於爲什麼工人的ID總是奇數而不是偶數的想法?

回答

2

您正在使用ExecutionContext.Implicits.global執行上下文。在引擎蓋下,它使用ForkJoinPool來處理工作線程。這個ForkJoinPool由Scala圖書館開發人員分發,以便根據他們的需求對其進行修改。你可以找到它here。請參閱函數registerWorker。工作人員名稱的結構是添加一個前綴(該變量名稱爲workerNamePrefix,默認值爲"ForkJoinPool-${POOL_ID}-worker-"),其索引始終以奇數(see line 1712)計算。因此,無論如何,這個數字總是很奇怪。這是由於實現的原因,它避免了掃描工作隊列的陣列,而是將其視爲一個二進制散列表(這需要雙散列的奇數索引)。您可以查看散列表上的一些很好的文檔以查找更多關於它)。

所以,你只需要1,3,5和7作爲工號,因爲可能你有一個4覈計算機。如果您希望它們在輸出中顯示得更加分散,則只需在工作中添加一些延遲,以便讓其他工作人員也可以繼續工作。像這樣:

def f(i: Int) = Future { println(db); Thread.sleep(100); 2 * i } 

希望它有幫助!

相關問題