保羅季馬的presentation,我發現了一個面試問題:什麼更難,同步2線程或1000線程?
什麼困難,同步2個線程或同步線程的1000?
從我的角度來看,當然同步1000個線程比較困難,但我想不出有什麼好的理由。但由於它的面試問題,可能是我錯了(面試的問題必須是棘手的,不是嗎?)。
保羅季馬的presentation,我發現了一個面試問題:什麼更難,同步2線程或1000線程?
什麼困難,同步2個線程或同步線程的1000?
從我的角度來看,當然同步1000個線程比較困難,但我想不出有什麼好的理由。但由於它的面試問題,可能是我錯了(面試的問題必須是棘手的,不是嗎?)。
同步千線程就像同步兩個線程一樣簡單:只需鎖定對所有重要數據的訪問。現在
,同步一千線程具有良好的性能是比較困難的。如果我問這個問題,我會尋找答案,提到「雷鳴羣體問題」,「鎖定爭用」,「鎖定實施可擴展性」,「避免自旋鎖」等。
爲什麼同步1000個線程比同步2個線程困難?
將被添加的唯一代碼是產生額外的線程。
你就不必添加任何同步碼(只要你正確地做的一切)。
這同樣困難。但是通過2個線程進行同步很可能會表現得更好,因爲只有2個線程會同時在一個鎖上而不是一千個,因爲鎖定的資源可能會導致更多的開銷。
希望這有助於
我認爲答案是,你必須同步兩個線程畢竟其他的998也將同步
對象不同步線程。創建同步的方法或代碼塊可以防止多個線程同時執行該區域 - 因此,如果有2,1000或1,000,000個線程,則無關緊要。
就性能而言,如果您希望在線程數加倍的情況下實現雙倍並行性(半執行時間),那麼任何同步區域在性能方面將成爲瓶頸,因爲它本質上是串行代碼這不能平行。
由於線程是同步的,而不是對象。對象(或更確切地說,連接到它們的監視器)是實現它的手段,但目標是協調(「同步」)執行代碼的線程。 – 2010-07-29 14:16:02
@Michael Borgwardt:這一切都取決於「同步」的意思,但通常我會說ACTIONS是需要同步的。大多數操作都涉及在某個對象上運行的THREAD。如果兩個線程正在做完全獨立的事情,那麼沒有辦法完全「同步」它們。雖然兩個相關的對象可能被描述爲彼此「同步」或「不同步」,但我不認爲這就是最初提出的問題。 – supercat 2010-07-29 14:26:09
這是唯一真正的答案是「它取決於」的問題之一。在這種情況下,這取決於你在做什麼。
情景可能是作爲一個後臺工作線程簡單的前臺等待,同時顯示進度表。或者它可以產生1000個線程,並在做其他事情之前等待它們全部完成。
可選地,如果少至2線程訪問共享資源,則該概念是相同的。對於併發性問題和鎖定策略,無論是2還是1000,都必須非常小心。無論多於多少個線程,都不能保證別的東西不會嘗試同時讀取或寫入到您所在的相同資源。
您可以使2個線程正確同步的情況實際上比1000個更難,因爲如果您有競爭條件,它通常會以1000個線程快速顯示,但只有2個不會顯示。
但在另一方面,同步1000線,而不會在鎖爭用問題是當只有有比更難2.
真正的答案是「同步線程是很難以各種方式,期限。」
+1「如果你有一個競爭條件,它通常會以1000個線程快速顯示,但只有2個線程會顯示非常快。」對我而言這是關鍵 - 但也許不是最明顯的答案。 – 2010-07-29 13:49:18
很好玩,先生。打的好。 – 2010-07-29 13:52:46
如果您使用像Scala這樣的編程語言來設計Actors模式,那麼您不必同步任何東西。 http://www.scala-lang.org/node/242
另一種選擇(在Java中)是使用比較和交換/設置機制http://en.wikipedia.org/wiki/Compare-and-swap,所以你不必同步任何線程,因爲它們是你正在比較和讀取的原子變量(非阻塞)並且只能根據您的解決方案阻止/等待寫入,從而獲得一些巨大的性能提升
我同意那些陳述「取決於」的說法。如果線程是相同的,那麼2和1000線程之間的差別不會那麼大。但是,如果有多個資源需要互斥訪問(以Java術語同步),則隨着線程數量的增加,死鎖的可能性可能會增加。
我有兩個答案。
我同意。有了兩個線程,資源分配非常簡單;當一個線程完成一個資源時,另一個線程獲取它。飢餓和優先倒置不是問題。對於三個或更多線程,需要注意防止飢餓(對於在其他線程中傳遞的資源,線程會無休止地等待)。如果實施優先級,則優先級反轉也可能是一個問題(等待低優先級線程佔用資源的最大優先級線程,而中等優先級線程佔用CPU)。那些只有兩個線程是非問題。 – supercat 2010-07-29 14:33:59
帶讀寫器問題。使用兩個線程,您可以使用互斥並完成。隨着更多的線程,你必須寫非平凡的代碼,因爲否則讀者不能同時閱讀,或者更糟的是,他們可能會扼殺作家。
但是,良好的同步代碼應該適用於任意數量的線程。在某些情況下,比如互斥,你可以添加Java的同步關鍵字,並且對於2個線程來說就像1000一樣困難。
換句話說,如果你的程序只使用2個線程,你可以利用它並做出假設這對於更多的線程來說是不正確的。顯然這不是一個好習慣,但它是可能的。
在一次採訪中,我會說「恰好兩個線程」是一個非常有用的多線程特例。像飢餓和優先級倒置這樣的事情可能發生在最少三個線程的情況下,但只有兩個線程優先級反轉和飢餓永遠不會發生(當然,如果一個線程釋放並重新獲得一個鎖而不讓另一個線程啓動,即使在可用時立即抓住鎖,也可能發生三個線程飢餓)。從2線程到3線比從3線到1000線更大。
當我瀏覽你的答案時,我發現了幾個有趣的內容。我認爲,在採訪中,這比答案更重要:轉換,嚴格。
從JVM或程序員的角度? – 2010-07-29 12:51:51
@Tim Buthe:不知道。我從幻燈片中複製了問題 – nanda 2010-07-29 12:54:00