同步问题
本文关键字:问题 同步 | 更新日期: 2023-09-27 18:24:47
我的代码(C#.NET 4)中有以下场景:
我有一个初始化为false的布尔变量:
bool b = false;
现在我正在实例化线程的数量,每个线程都需要读取b的值。第一个读取b-的线程应该将其值更改为true(并执行一些逻辑…),而其他线程则不应该执行任何操作。在读取"b"的值时,我需要对其使用同步机制吗?还是只能在将其值设置为true时锁定它?这应该能提高我的表现,但我想知道它是否安全。。
所以要求是:
- 多个线程读取单个
bool
变量 - 如果线程看到
false
值,它应该将其更改为true
并执行额外的工作 - 如果线程看到
true
值,则不应该发生其他任何事情 - 应该只有一个线程能够更改值并执行额外的工作
所以代码看起来像:
public class Example
{
private bool b = false;
public void DoSomething()
{
if (!b)
{
b = true;
DoExtraStuff();
}
}
}
当然,如果有多个线程执行DoSomething
,并且意图是DoExtraStuff
应该只执行一次,那么这是不安全的。问题是线程将在b
的读写上竞争。
您确实需要使对b
的读写成为原子。这可以使用lock
关键字来完成。
public class Example
{
private bool b = false;
private object locker = new object();
public void DoSomething()
{
bool trigger = false;
lock (locker)
{
if (!b)
{
b = true;
trigger = true;
}
}
if (trigger)
{
DoExtraStuff();
}
}
}
存在经由Interlocked.CompareExhange
使用CAS操作的替代模式。不幸的是,没有接受bool
的重载,但如果您愿意将该bool
更改为int
,则以下操作也适用。
public class Example
{
private int b = 0;
public void DoSomething()
{
if (Interlocked.CompareExchange(ref b, 0, 1) == 0)
{
DoExtraStuff();
}
}
}