Pat*_*ski 16 c# multithreading thread-safety
我对这个主题非常困惑 - 读取/切换bool值是否是线程安全的.
// case one, nothing
private bool v1;
public bool V1 { get { return v1; } set { v1 = value; } }
// case two, with Interlocked on set
private int v2;
public int V2 { get { return v2; } set { Interlocked.Exchange(ref v2, value); } }
// case three, with lock on set
private object fieldLock = new object();
private bool v3;
public bool V3 { get { return v3; } set { lock (fieldLock) v3 = value; } }
Run Code Online (Sandbox Code Playgroud)
它们都是线程安全的吗?
编辑
从我所读到的(点击)bool的原子性不保证它将是线程安全的.那么会volatile输入帮助吗?
Yur*_*ura 24
不,并非所有这些都是线程安全的.
案例一实际上并不完全是线程安全的,或者更好的说法 - 它根本不是线程安全的.即使使用boolean的操作是原子的,变量值也可以存储在缓存中,因此,如在多核CPU中每个核心都有自己的缓存,值可能会被破坏.
更进一步,编译器和CPU可以执行一些内部优化,包括指令重新排序,这可能会对程序的逻辑产生不利影响.
您可以添加volatile关键字,以通知编译器该字段在多线程上下文中使用.它将修复缓存和指令重新排序的问题,但不会给你真正的"线程安全"代码(因为写操作仍然不会同步).也volatile不能应用于局部变量.
因此,在处理多线程时,您总是必须在有价值的资源上使用一些线程同步技术.
有关更多信息 - 请阅读此答案,该答案对不同技术有更深入的解释.(例如有关int,但并不重要,它描述了一般方法.)
lil*_*lo0 14
有点晚了但应该对其他人有用.
您可以通过以下方式实现自己的线程安全布尔值:
// default is false, set 1 for true.
private int _threadSafeBoolBackValue = 0;
public bool ThreadSafeBool
{
get { return (Interlocked.CompareExchange(ref _threadSafeBoolBackValue, 1, 1) == 1); }
set
{
if (value) Interlocked.CompareExchange(ref _threadSafeBoolBackValue, 1, 0);
else Interlocked.CompareExchange(ref _threadSafeBoolBackValue, 0, 1);
}
}
Run Code Online (Sandbox Code Playgroud)
一定要在所有地方使用Property,永远不要int直接访问变量.
Ron*_*ovi 10
不,不是。但解决方案很简单。为了使 bool (或实际上的任何东西)线程安全,很容易使用像这样的lock语句:
object locker = new object();
protected bool _somebool;
public bool Somebool
{
get
{
lock (locker)
return _somebool;
}
set
{
lock (locker)
_somebool = value;
}
}
Run Code Online (Sandbox Code Playgroud)
现在您可以享受您的线程安全了<T>。
| 归档时间: |
|
| 查看次数: |
18273 次 |
| 最近记录: |