2012-11-08 98 views
1

我正在處理一棵樹,並且希望使用GPAR加速它。我已經將它用於簡單的事情,但還沒有深入到更復雜的選項。使用GPars處理緩存已處理節點的樹中的節點

假設我正在用自己的線程處理樹的不同分支。

假設一個節點有一個名字。當我第一次打那個節點時,我希望它被處理(包括將事情寫入數據庫等),並添加到緩存中(這裏只是一個簡單的地圖)。

我想要其他線程可能擊中樹上其他地方的同一節點(例如,具有相同名稱的節點)來檢查緩存。如果它已經在緩存中,他們可以抓住它並繼續前進。如果另一個線程第一次處理該節點,我希望分支中該節點上的其他線程在繼續執行樹之前等待(取決於已經處理該節點的其他事物)。

節點是從數據庫中拉出來的,所以它不是每個分支中的同一個對象,我不認爲同步方法可以工作。

我當然希望其他不相關的節點繼續處理。

例如:

  • 線程1的處理ABCD
  • 線程2是加工EBFG
  • 線程3是處理WXY
  • 螺紋4被處理LMNOPQRSBJ

比方說線程1首先到達節點B.它發現它不在緩存中,所以它開始處理它。

線程2出現,看到節點B不在緩存中,但它正在工作。所以它等到節點F,直到線程1完成處理節點B.

線程3不關心節點B,因此一直保持啓動狀態。

線程4線程1已與B節點完成後,沿後話和高速緩存中找到節點B,所以它只是拉它從緩存中,並繼續到節點J.

我要找的建議我如何最好地將GPAR應用於這種情況。

謝謝!

回答

2

我的第一個想法是使用一個共享的ConcurrentHashmap,其中節點名稱作爲鍵和DataflowVariables作爲值。

線程使用putIfAbsent(nodename,new DataflowVariable())自動爲已處理節點的數據插入一個承諾,如果操作成功執行,則可能會開始處理該節點並最終將結果綁定到DataflowVariable。

如果putIfAbsent()失敗,則其他某個線程已經開始處理具有相同名稱的節點。在這種情況下,當前線程可能會抓取與節點名相關的DataflowVarieble,並等待結果可用 - 調用get()或whenBound()。

+0

因此,對於上面的線程4,它應該先在hashmap上執行get(),然後執行putIfAbsent()?或者應該每個線程總是執行putIfAbsent,那麼如果很久以前處理了該項目,那麼DataFlowVariable將始終從get()快速返回?順便說一句,我不能投票你的答案(我試過)B/C我沒有聲望15尚未;-) – user1373467

+0

和一個愚蠢的問題 - 我迭代使用eachParallel,我可以直接使用DataFlowVariable,或者我需要使用DataFlow任務?謝謝! – user1373467

+0

您可能會也可能不會在putIfAbsent()之前調用get()。假如get()返回非null的概率很高,它可以通過避免構建永遠不會使用的DataflowVariables來節省一些處理時間。但是,如果get()返回null,則不應該進行假設,並且必須遵循putIfAbsent(),因爲它是保證原子性的putIfAbsent()。 –