C# 同步问题
我的代码(C#.NET 4)中有以下场景: 我有一个初始化为false的布尔变量:C# 同步问题,c#,.net,multithreading,synchronization,C#,.net,Multithreading,Synchronization,我的代码(C#.NET 4)中有以下场景: 我有一个初始化为false的布尔变量: bool b = false; 现在我正在实例化线程的数量,每个线程都需要读取b的值。第一个读取b-的线程应该将其值更改为true(并执行一些逻辑…),而其他线程不应该执行任何操作。读取“b”的值时是否需要使用同步机制,或者只能在将其值设置为true时锁定它? 这将提高我的性能,但我想知道它是否安全。因此要求如下: 多个线程读取单个bool变量 如果线程看到一个false值,它应该将其更改为true,并执行额
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();
}
}
}
有一种备用模式,使用通过联锁的操作。CompareExhange
。不幸的是,没有接受bool
的重载,但是如果您愿意将bool
更改为int
,以下操作也可以
public class Example
{
private int b = 0;
public void DoSomething()
{
if (Interlocked.CompareExchange(ref b, 0, 1) == 0)
{
DoExtraStuff();
}
}
}
因此,要求如下:
- 多个线程读取单个
变量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();
}
}
}
有一种备用模式,使用通过联锁的操作。CompareExhange
。不幸的是,没有接受bool
的重载,但是如果您愿意将bool
更改为int
,以下操作也可以
public class Example
{
private int b = 0;
public void DoSomething()
{
if (Interlocked.CompareExchange(ref b, 0, 1) == 0)
{
DoExtraStuff();
}
}
}
你是对的。多个线程可能会看到'!b'为true,将输入if-block。是的,您是对的,这是正确的版本。希望OP会出现并更改已接受的答案,以便我可以删除我的答案。我似乎误解了他想做什么。@Tudor:是的,误解的问题经常发生在我身上。这个问题的措辞本可以再好一点,你是对的。多个线程可能会看到'!b'为true,将输入if-block。是的,您是对的,这是正确的版本。希望OP会出现并更改已接受的答案,以便我可以删除我的答案。我似乎误解了他想做什么。@Tudor:是的,误解的问题经常发生在我身上。这个问题的措辞本可以再好一点。