2011-12-28 90 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