2010-07-29 40 views
11

保羅季馬的presentation,我發現了一個面試問題:什麼更難,同步2線程或1000線程?

什麼困難,同步2個線程或同步線程的1000?

從我的角度來看,當然同步1000個線程比較困難,但我想不出有什麼好的理由。但由於它的面試問題,可能是我錯了(面試的問題必須是棘手的,不是嗎?)。

+3

從JVM或程序員的角度? – 2010-07-29 12:51:51

+0

@Tim Buthe:不知道。我從幻燈片中複製了問題 – nanda 2010-07-29 12:54:00

回答

14

同步千線程就像同步兩個線程一樣簡單:只需鎖定對所有重要數據的訪問。現在

,同步一千線程具有良好的性能是比較困難的。如果我問這個問題,我會尋找答案,提到「雷鳴羣體問題」,「鎖定爭用」,「鎖定實施可擴展性」,「避免自旋鎖」等。

3

爲什麼同步1000個線程比同步2個線程困難?

將被添加的唯一代碼是產生額外的線程。

你就不必添加任何同步碼(只要你正確地做的一切)。

0

這同樣困難。但是通過2個線程進行同步很可能會表現得更好,因爲只有2個線程會同時在一個鎖上而不是一千個,因爲鎖定的資源可能會導致更多的開銷。

希望這有助於

3

我認爲答案是,你必須同步兩個線程畢竟其他的998也將同步

0

對象不同步線程。創建同步的方法或代碼塊可以防止多個線程同時執行該區域 - 因此,如果有2,1000或1,000,000個線程,則無關緊要。

就性能而言,如果您希望在線程數加倍的情況下實現雙倍並行性(半執行時間),那麼任何同步區域在性能方面將成爲瓶頸,因爲它本質上是串行代碼這不能平行。

+0

由於線程是同步的,而不是對象。對象(或更確切地說,連接到它們的監視器)是實現它的手段,但目標是協調(「同步」)執行代碼的線程。 – 2010-07-29 14:16:02

+0

@Michael Borgwardt:這一切都取決於「同步」的意思,但通常我會說ACTIONS是需要同步的。大多數操作都涉及在某個對象上運行的THREAD。如果兩個線程正在做完全獨立的事情,那麼沒有辦法完全「同步」它們。雖然兩個相關的對象可能被描述爲彼此「同步」或「不同步」,但我不認爲這就是最初提出的問題。 – supercat 2010-07-29 14:26:09

1

這是唯一真正的答案是「它取決於」的問題之一。在這種情況下,這取決於你在做什麼。

情景可能是作爲一個後臺工作線程簡單的前臺等待,同時顯示進度表。或者它可以產生1000個線程,並在做其他事情之前等待它們全部完成。

可選地,如果少至2線程訪問共享資源,則該概念是相同的。對於併發性問題和鎖定策略,無論是2還是1000,都必須非常小心。無論多於多少個線程,都不能保證別的東西不會嘗試同時讀取或寫入到您所在的相同資源。

38

您可以使2個線程正確同步的情況實際上比1000個更難,因爲如果您有競爭條件,它通常會以1000個線程快速顯示,但只有2個不會顯示。

但在另一方面,同步1000線,而不會在鎖爭用問題是當只有有比更難2.

真正的答案是「同步線程是很難以各種方式,期限。」

+3

+1「如果你有一個競爭條件,它通常會以1000個線程快速顯示,但只有2個線程會顯示非常快。」對我而言這是關鍵 - 但也許不是最明顯的答案。 – 2010-07-29 13:49:18

+1

很好玩,先生。打的好。 – 2010-07-29 13:52:46

0

如果您使用像Scala這樣的編程語言來設計Actors模式,那麼您不必同步任何東西。 http://www.scala-lang.org/node/242

另一種選擇(在Java中)是使用比較和交換/設置機制http://en.wikipedia.org/wiki/Compare-and-swap,所以你不必同步任何線程,因爲它們是你正在比較和讀取的原子變量(非阻塞)並且只能根據您的解決方案阻止/等待寫入,從而獲得一些巨大的性能提升

+0

這並非完全正確。我喜歡斯卡拉,但仍然存在共享有限資源的問題。也就是說,只能有這麼多的套接字,寫入/讀取給定文件的人等。 – wheaties 2010-07-29 13:08:27

+1

我真的很喜歡Compare-And-Swap;我想知道爲什麼我沒有看到它推動更多。更令人感興趣的是我在白皮書中看到的一個2級條件加載原語,該原語在硬件中應該切實可行,並且可以實現實際的雙重比較和交換。 DCAS允許非常實用的無鎖數據結構。由於我討厭鎖定,我認爲一個實際的DCAS會非常有用。 – supercat 2010-07-29 14:28:23

3

這取決於「更容易」的含義。設計/鎖定機制的複雜性大致相同。

這就是說,我認爲1000線程程序可能更容易debug。脆弱的種族條件發生的概率較高,並可能更容易複製。如果月亮已滿並且您正在度假,兩條線索中的競賽條件可能只會每5年出現一次。

+1

更容易複製但難以解決? – nanda 2010-07-29 13:10:31

+2

困難的部分是弄清楚它存在問題,它是什麼以及它在哪裏。能夠可靠地複製錯誤條件使問題更容易解決。 – jdizzle 2010-07-29 13:56:51

+0

+1「你正在度假」* g – Daniel 2011-03-04 20:03:41

1

我同意那些陳述「取決於」的說法。如果線程是相同的,那麼2和1000線程之間的差別不會那麼大。但是,如果有多個資源需要互斥訪問(以Java術語同步),則隨着線程數量的增加,死鎖的可能性可能會增加。

3

我有兩個答案。

  1. CASE 1:利用現有資源:同步2個線程是相同的困難,因爲由於現有的用於同步的線程的任意數量的創建同步1000個線程。
  2. 案例2:從零開始實施似乎很明顯,如果您必須從頭開始實施同步系統,那麼構建2線程系統會更容易。
+3

我同意。有了兩個線程,資源分配非常簡單;當一個線程完成一個資源時,另一個線程獲取它。飢餓和優先倒置不是問題。對於三個或更多線程,需要注意防止飢餓(對於在其他線程中傳遞的資源,線程會無休止地等待)。如果實施優先級,則優先級反轉也可能是一個問題(等待低優先級線程佔用資源的最大優先級線程,而中等優先級線程佔用CPU)。那些只有兩個線程是非問題。 – supercat 2010-07-29 14:33:59

2

帶讀寫器問題。使用兩個線程,您可以使用互斥並完成。隨着更多的線程,你必須寫非平凡的代碼,因爲否則讀者不能同時閱讀,或者更糟的是,他們可能會扼殺作家。

但是,良好的同步代碼應該適用於任意數量的線程。在某些情況下,比如互斥,你可以添加Java的同步關鍵字,並且對於2個線程來說就像1000一樣困難。

換句話說,如果你的程序只使用2個線程,你可以利用它並做出假設這對於更多的線程來說是不正確的。顯然這不是一個好習慣,但它是可能的。

4

在一次採訪中,我會說「恰好兩個線程」是一個非常有用的多線程特例。像飢餓和優先級倒置這樣的事情可能發生在最少三個線程的情況下,但只有兩個線程優先級反轉和飢餓永遠不會發生(當然,如果一個線程釋放並重新獲得一個鎖而不讓另一個線程啓動,即使在可用時立即抓住鎖,也可能發生三個線程飢餓)。從2線程到3線比從3線到1000線更大。

1

當我瀏覽你的答案時,我發現了幾個有趣的內容。我認爲,在採訪中,這比答案更重要:轉換,嚴格。