考慮到以下要求,有人可以發佈一個非常簡單的代碼示例,說明如何使用多線程,並同時正確使用鎖來保持共享數據「安全」?簡單線程示例需要
假設你聲明一個整數x爲100.然後,你想產生10個線程來執行一些操作。隨着每個線程完成該動作,它會遞減x。我知道你可以使用互鎖,但是當你評估這種情況時你是否也需要鎖定?換句話說,在執行操作之前,您需要確保x大於0。
考慮到以下要求,有人可以發佈一個非常簡單的代碼示例,說明如何使用多線程,並同時正確使用鎖來保持共享數據「安全」?簡單線程示例需要
假設你聲明一個整數x爲100.然後,你想產生10個線程來執行一些操作。隨着每個線程完成該動作,它會遞減x。我知道你可以使用互鎖,但是當你評估這種情況時你是否也需要鎖定?換句話說,在執行操作之前,您需要確保x大於0。
你可以用每次訪問x
與lock
關鍵字:
private object xLock = new object();
...
lock (xLock)
{
// Any read or write access to x
}
這將確保是原子的所有訪問在X,並沒有對線程安全相關的危險。
如果你想要做的事情只是版本實現自己的邏輯
lock(somecommonreference)
{
if (x>0) x--;
}
如果要編寫簡單的多線程程序,考慮在C#4.0使用並行擴展。
簡單的多線程程序與鎖和可變的共享數據是從來沒有簡單。
你可能不想減少計數器操作完成後,作爲計數器可以是1,所有10個線程會檢查它,發現它是大於零,並開始執行行動,只有所有在完成時遞減。
您可以使用Interlocked.Decrement遞減計數器和執行操作前檢查它的價值不鎖定:
int temp = Interlocked.Decrement(x);
if(temp >= 0) //temp is the decremented value
{
//perform action
}
你想用Interlocked.CompareExchange。假設您要修改名爲Counter
的共享變量。
int count = Counter;
if (count == 0)
return;
if (Interlocked.CompareExchange(ref Counter, count-1, count) == count)
{
// Counter was decremented.
// perform your processing.
}
如果您希望線程在退出前最多處理10個項目,可以將其包裝在一個循環中。
請注意,計數器控制條目的處理方法。也就是說,在邏輯上它的工作原理是這樣的:
if (counter > 0)
{
--counter;
DoAction();
}
你的問題似乎問這樣的事情:
if (counter > 0)
{
DoAction();
--counter;
}
但是,如果你這樣的代碼,那麼你很可能會調用超過100 DoAction
更多次數(或者counter
的初始值),因爲其他線程可以在最後一個線程完成之前開始動作。
是的,但如果操作失敗會怎麼樣。我不想減少。 – JedMoney 2011-03-18 21:54:28
行動失敗的可能性使它更復雜一點。您可能希望查看C#4.0中的並行擴展,作爲jdv在他的回答中提出的建議,並在嘗試設計自己的設計之前查看是否適合您的要求。多線程程序很容易很快變得非常複雜。 – 2011-03-18 22:39:37