2011-09-19 55 views
2

假設我有一個多線程應用程序讀取和寫入的項目集合。當涉及到在一些項目上應用算法時,我會用不同的方法獲取鎖。通常鎖定集合的最佳方法是什麼?

通過在整個操作過程中鎖定:

lock(collection) 
{ 
    for each thing in things 
    { 
     get the item from collection that matches thing 
     do stuff with item 
    } 
} 

受需求鎖定在:

for each thing in things 
{ 
    lock(collection) 
    { 
     get the item from collection that matches thing 
    } 
    do stuff with item 
} 

或者通過鎖定按需獲取項目的線程安全集合後處理,因此具有收藏鎖定時間較短:

Items items 
for each thing in things 
{ 
    lock(collection) 
    { 
     get the item from collection that matches thing 
    } 
    items.Add(item) 
} 
for each item in items 
{ 
    do stuff with item 
} 

我知道它最終可能會依靠應用於每個項目的實際算法,但你會做什麼?我正在使用C++,但我非常確定它是無關緊要的。

回答

2

看看Double Check lock模式,其中涉及鎖定下的收集/字段的單獨字段。

也值得去看一看的Readers-writer lock技術,它允許讀取,而另一線程更新的集合

編輯: 當大衛赫弗南提到看一看的​​討論

+0

無論這種技術,你會怎麼做我的情況? –

+0

查看更新後的答案,想法是將單獨的字段/變量與集合一起引入,並鎖定該集合或每個元素的鎖定的特定字段(前者是一團糟!) – sll

+0

不建議在沒有討論「雙重檢查鎖定已損壞」聲明。 –

0

鎖定獲取和釋放是昂貴的。我會鎖定集合而不是循環中的每個單獨元素。如果整個操作需要原子化,這是有道理的。

2

在一個多線程設置,帶有線程讀寫功能,你的第一個和第二個例子有不同的含義。如果「用項目做某事」與其他線程交互,你的第三個例子可能會有另一個含義。

在決定如何去做之前,你需要決定你想要的代碼。

+0

「與物品做某事」將與其他線索進行交互,但不會與使用我收藏物品的線程進行交互。 –

相關問題