2011-03-18 85 views
0

考虑到以下要求,有人可以发布一个非常简单的代码示例,说明如何使用多线程,并同时正确使用锁来保持共享数据“安全”?简单线程示例需要

假设你声明一个整数x为100.然后,你想产生10个线程来执行一些操作。随着每个线程完成该动作,它会递减x。我知道你可以使用互锁,但是当你评估这种情况时你是否也需要锁定?换句话说,在执行操作之前,您需要确保x大于0。

回答

4

你可以用每次访问xlock关键字:

private object xLock = new object(); 

... 

lock (xLock) 
{ 
    // Any read or write access to x 
} 

这将确保是原子的所有访问在X,并没有对线程安全相关的危险。

0

如果你想要做的事情只是版本实现自己的逻辑

lock(somecommonreference) 
{ 
    if (x>0) x--; 
} 
4

如果要编写简单的多线程程序,考虑在C#4.0使用并行扩展。

简单的多线程程序与锁和可变的共享数据是从来没有简单。

2

你可能不想减少计数器操作完成后,作为计数器可以是1,所有10个线程会检查它,发现它是大于零,并开始执行行动,只有所有在完成时递减。

您可以使用Interlocked.Decrement递减计数器和执行操作前检查它的价值不锁定:

int temp = Interlocked.Decrement(x); 

if(temp >= 0) //temp is the decremented value 
{ 
    //perform action 
} 
+0

是的,但如果操作失败会怎么样。我不想减少。 – JedMoney 2011-03-18 21:54:28

+0

行动失败的可能性使它更复杂一点。您可能希望查看C#4.0中的并行扩展,作为jdv在他的回答中提出的建议,并在尝试设计自己的设计之前查看是否适合您的要求。多线程程序很容易很快变得非常复杂。 – 2011-03-18 22:39:37

2

你想用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的初始值),因为其他线程可以在最后一个线程完成之前开始动作。