锁定一个简单的属性 - 它会死锁吗?
问题:
- 我可以让这段代码陷入死锁吗? IsMouseInside 属性是线程安全的吗?
- 使用复制变量有意义吗?
PS:UI线程更新IsMouseInside。另一个线程有时会读取它的值
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;
}
}
Questions:
- Can I deadlock this code? Does the IsMouseInside property is thread safe?
- Does the use of the copy variable make sense?
PS: UI thread updates IsMouseInside. Another thread will read its value some times
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;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
![扫码二维码加入Web技术交流群](/public/img/jiaqun_03.jpg)
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
return isMouseInside;
return isMouseInside;
不,这不会陷入僵局;只有一个锁对象,并且不存在允许您在持有锁时做一些混乱的事情的扩展点。但是,如果您正在使用锁,您应该明确要避免的情况。虽然含义实际上非常微妙,但我想知道
易失性
是否可以在不需要任何锁的情况下在这里工作。或者在始终为0
或1
的int
上进行Interlocked
。但当然,看起来它会起作用;无论如何,bool 始终是原子的,因此这里的锁实际上只是充当内存屏障,避免缓存问题(因此 volatile 也可能起作用)。请记住,任何时候您获得的值都已过时,并且可能已经不正确。不过,在阅读时确实如此。
No that can't deadlock; there is only one lock object, and no extension point exists that would allow you to do something messy while the lock is held. However, if you are using lock you should probably make it clear what scenarios you are trying to avoid. While the meaning is actually very subtle, I wonder whether
volatile
might work here without needing any locks. OrInterlocked
on anint
that is always either0
or1
.But sure, it looks like it'll work; bool is always atomic anyway, so the lock here is only really acting as a memory-barrier avoiding cache issues (hence why volatile might also work). And remember that any time you get the value, that is now stale and might already be incorrect. It was true at the point of read, though.
目标是什么?
What is the goal?
只有当两个不同的线程尝试以不同的顺序获取两个不同的锁 A 和 B 时,才会出现死锁 - 因为这里只有一个锁,所以是安全的。
另请记住,C# 锁(这是使用 的语法糖) Monitor)是可重入 - 单个线程不会死锁,因为它可以重新进入锁一旦它最初获得它,就可以多次使用。
You can only have a deadlock if you have two different locks A and B that two different threads try to acquire in different order - since you only have one lock here you are safe.
Also keep in mind that C# lock (which is syntactic sugar for using a Monitor) is reentrant - a single thread cannot deadlock since it can reenter a lock as many times as it wants to once it has initially acquired it.