2011-12-28 97 views
3

使用the lock statement,可以「確保一個線程不會進入關鍵代碼段,而另一個線程進入關鍵段,如果另一個線程嘗試輸入被鎖定的代碼,它將等待,阻止,直到對象被釋放「。如何在鎖定語句中實現互斥?但是如果鎖定被鎖定,該塊會被跳過?

如果我想要的行爲是,如果另一個線程試圖進入鎖定的代碼,它會跳過整個代碼(而不是等待鎖釋放)?浮現在我的腦海裏的想法是使用一個標誌,像

if(flag) return; 
flag = true; 
//do stuff here 
flag =false; 

但我知道這是不是安全的,因爲兩個線程可以通過第一行之前任何人都設置爲true,或者該標誌被永遠不會設置爲false在例外的情況下..你能提出改進還是替代方案?

回答

5

Monitor.TryEnter使用this overload,它可以讓你指定超時。

嘗試在指定的時間內獲取對指定對象的獨佔鎖 。

返回值類型:System.Boolean如果當前線程獲取了鎖,則爲true ;否則,是錯誤的。

在你的情況,你可能想使用的接近一個超時TimeSpan.Zero

如果你不希望線程嘗試把鎖等待任何長的時間內,你的Monitor.TryEnter只是this overload,不接受TimeSpan說法。這種方法會立即返回而不用等待 - 非常接近您嘗試使用的標誌技術的情緒。

+0

爲什麼你認爲我想使用接近零的超時?爲什麼不只是零? – 2011-12-28 05:46:37

+0

@Louis:你可以使用0的時間間隔(或者等價地,使用另一個不需要TimeSpan的超載)。在放棄之前至少等待一小段時間的資源是很常見的。你不必,如果你不想。 :) – Ani 2011-12-28 05:48:37

1

你需要Semaphores與限制1和超時時間0毫秒

通過使用旗語你可以說,只有線程的數量有限,在同一時間訪問一段代碼。

如何使用它

this sample您需要使用此方法等待

bool WaitOne(int millisecondsTimeout) 

指定超時時間= 0;這樣你的等待線程將等待0秒這意味着他們會簡單地跳過代碼

Example

class SemaphoreExample  
{ 
// Three reserved slots for threads 
public static Semaphore Pool = new Semaphore(1, 0); 

public static void Main(string[] args) 
{  
// Create and start 20 threads  
for (int i = 0; i < 20; i++) 
{ 
    Thread t = new Thread(new ThreadStart(DoWork)); 
    t.Start(); 
} 

Console.ReadLine();  
} 

private static void DoWork()  
{  
// Wait 0 miliseconds 
SemaphoreExample.Pool.WaitOne(0); 


#region Area Protected By Semaphore  
Console.WriteLine("Acquired slot..."); 

for (int i = 0; i < 10; i++) 
{ 
    Console.WriteLine(i + 1); 
} 
Console.WriteLine("Released slot...");  

#endregion   
// Release the semaphore slot  
SemaphoreExample.Pool.Release();  
}  
} 
+0

如何運作的? – 2011-12-28 05:30:49

+0

查看已更新的答案 – 2011-12-28 05:40:22