C# 锁定在一个简单的属性中-它会死锁吗?
问题:C# 锁定在一个简单的属性中-它会死锁吗?,c#,locking,deadlock,C#,Locking,Deadlock,问题: 我可以死锁这个代码吗?IsMouseInside属性是线程安全的吗 copy变量的使用有意义吗 PS:UI线程更新在内部。另一个线程将多次读取其值 public Class Test { private readonly object isMouseInsideLocker = new object(); private bool isMouseInside = false; public bool IsMouseInside
PS:UI线程更新在内部。另一个线程将多次读取其值
public Class Test
{
private readonly object isMouseInsideLocker = new object();
private bool isMouseInside = false;
public bool IsMouseInside
{
get
{
bool copy;
lock (this.isMouseInsideLocker)
copy = this.isMouseInside;
return copy;
}
set
{
lock (this.isMouseInsideLocker)
this.isMouseInside = value;
}
}
private void lblProcessTime_MouseEnter(object sender, EventArgs e)
{
IsMouseInside = true;
}
private void lblProcessTime_MouseLeave(object sender, EventArgs e)
{
IsMouseInside = false;
}
}
目标是什么?只有当两个不同的线程以不同的顺序尝试获取两个不同的锁a和B时,才会出现死锁-因为这里只有一个锁,所以是安全的
还要记住C#lock(这是使用a的语法糖)is-单个线程不能死锁,因为它可以在初始获取锁后按其希望的次数重新输入锁。只有当两个不同线程尝试以不同顺序获取两个不同的锁a和B时,才会出现死锁-因为这里只有一个锁,所以您是安全的
还请记住,C#lock(使用a的语法糖)是-单个线程不能死锁,因为一旦它最初获得锁,它可以根据自己的意愿多次重新输入锁。不,不能死锁;只有一个lock对象,并且不存在允许您在保持锁的同时执行一些混乱操作的扩展点。然而,如果您使用的是lock,您可能应该清楚地说明您试图避免的场景。虽然其含义实际上非常微妙,但我想知道
volatile
是否可以在不需要任何锁的情况下在这里工作。或在始终为0
或1
的int
上联锁
但当然,它看起来会起作用;bool始终是原子的,因此这里的锁实际上只是作为一个内存屏障,以避免缓存问题(因此为什么volatile也可以工作)。记住,任何时候你得到的值,现在都是过时的,可能已经不正确了。不过,在读的时候确实如此。不,不能死锁;只有一个lock对象,并且不存在允许您在保持锁的同时执行一些混乱操作的扩展点。然而,如果您使用的是lock,您可能应该清楚地说明您试图避免的场景。虽然其含义实际上非常微妙,但我想知道volatile
是否可以在不需要任何锁的情况下在这里工作。或在始终为0
或1
的int
上联锁
但当然,它看起来会起作用;bool始终是原子的,因此这里的锁实际上只是作为一个内存屏障,以避免缓存问题(因此为什么volatile也可以工作)。记住,任何时候你得到的值,现在都是过时的,可能已经不正确了。不过,从阅读的角度来看,这是真的
不,你不能
没有。只需返回内部代码>
不,你不能
没有。只需返回内部代码>
UI线程更新在内部。另一个线程会多次读取它的值,这就是我使用锁的原因。好吧,但是你只锁定了一个操作。你没必要这么做。对不起,你能解释一下吗?锁定bool只对内存屏障有用,因为它是一个原子变量?UI线程更新在内部。另一个线程会多次读取它的值,这就是我使用锁的原因。好吧,但是你只锁定了一个操作。你没必要这么做。对不起,你能解释一下吗?锁定布尔只对内存屏障有用,因为它是一个原子变量?我想我可以用X+=X这样的东西来死锁,X是一个int,并使用我使用过的那种锁。@Pedro:这仍然有效,因为lock
是可重入的:@Pedro X+=X怎么会是死锁?在最坏的情况下,可能是由于冲突导致的数据丢失(最好是Interlocked.Add),但这与死锁不同。@BrokenGlass在该场景中,重入是不相关的;这是两个“get”和一个“set”-但每个单独。当然,除非你明确地锁定持续时间,但是访问器中的锁似乎没有必要。我想我可以用X+=X这样的东西来死锁,X是一个int,并且使用我曾经使用过的那种锁。@Pedro:这仍然有效,因为lock
是可重入的:@Pedro X+=X怎么会是死锁?在最坏的情况下,可能是由于冲突导致的数据丢失(最好是Interlocked.Add),但这与死锁不同。@BrokenGlass在该场景中,重入是不相关的;这是两个“get”和一个“set”-但每个单独。当然,除非明确锁定持续时间,否则访问器中的锁定似乎是不必要的。要确定“线程安全”,我们需要知道上下文是如何使用的。PS:UI线程更新IsMouseInside。另一个线程会在没有某种内存障碍的情况下读取其值,您接受的答案可能无法保证有效(它可能被缓存);然而,决定哪种方式都很复杂。就我个人而言,我会在这里使用一些东西——不仅仅是一个裸字段访问器。但是锁不是一个内存屏障吗?你能再解释一下吗?是的;我的意思是:在接受的答案中不清楚它是否仍在使用锁
——它需要一些东西来确定“线程安全”,我们需要知道它是如何使用的上下文。PS:UI线程更新在内部。另一个线程会在没有某种内存障碍的情况下读取其值,您接受的答案可能无法保证有效(它可能被缓存);然而,决定哪种方式都很复杂。每