2013-05-14 28 views
4

我有這樣的方法:兩個實例(同步某個對象)平行

public void processChildNodes(Node result, Node source) { 
    synchronized (source) { 
     NodeList nodes = source.getChildNodes(); 
     for (int i = 0; i < nodes.getLength(); i++) { 
      processNode(result, nodes.item(i)); 
     } 
    } 
    } 

現在,讓我們說,我想打電話給processChildNodes與類的兩個不同的實例中,這方法是相同的來源(方法的第二個參數),是否有可能這兩個執行可以並行?

+1

答案是,不。 – Mordechai 2013-05-14 05:43:01

+0

爲什麼這與單個對象上的同步有什麼不同?由於'source'在兩次調用中都指向同一個對象,因此它將與在單個對象上進行同步的行爲相同。爲何混淆? – brainOverflow 2013-05-14 06:22:43

回答

2

不,該方法將被調用,但同步塊內的內容不會並行執行。這是因爲你已經提到你正在使用相同的源對象。由於在對象上獲取鎖定,所以同步將正常工作。

0

Java是通過值,意思是Node傳遞實際上是一個副本。系統爲兩個獨立的方法調用創建兩個單獨的副本,這意味着這兩個副本將並行執行。請注意,這也意味着您的同步塊可能無效。小心數據競賽。

編輯

我做了一點研究,發現this page描述參數是如何工作的。鑑於這些新的信息,我認爲我的答案是無效的,但我仍然不能100%確定。

+0

線程不鎖定參考!?! – Mordechai 2013-05-14 05:46:45

+2

這不完全正確。 Java會傳遞一個指向Node的副本。所以Node的價值是共享的,而不是副本。因此,您將在同一個對象上進行同步。 – 2013-05-14 05:48:13

+0

布拉沃,你有勇氣承認錯誤.. [至少只要你保持匿名...] – Mordechai 2013-05-14 05:59:12

2

您正嘗試進行對象鎖定。如果你傳遞了相同的對象,那麼你的處理將被同步,這意味着一個線程將執行同步塊內的代碼,另一個線程將等待它。但是如果你傳遞兩個不同的對象,那麼它們將使用兩個不同的鎖,這意味着它們不依賴於彼此來獲取鎖。所以他們都會並行執行。

正如您編寫代碼並嘗試使用源對象來同步執行一樣。因此,請確保您的兩個線程都使用相同的源對象來獲得所需的結果。

+0

嗯我同意你,但基於行爲我看到它似乎同步塊正在執行並行調用方法使用兩個不同的類對象具有相同的源對象。 – user999491 2013-05-14 06:01:56

+0

您可以共享創建節點對象的代碼以及調用processChildNodes的代碼。 – 2013-05-14 06:06:17

+0

是的,我確定我會分享一段時間 – user999491 2013-05-14 06:15:50

1

因爲您使用源對象來同步同步應該正常工作。如果兩個實例中使用的對象不同,則兩個執行可能並行發生。