Raf*_*afa 24 c# multithreading
实现锁时,我曾经在我的类中创建一个私有对象:
如果我想确保它被锁定在创建我的类的线程中:
private object Locker = new object();
Run Code Online (Sandbox Code Playgroud)
如果我想确保它将被锁定我的应用程序中的所有线程:
private static object Locker = new object();
Run Code Online (Sandbox Code Playgroud)
但是这里: 为什么锁定对象必须是静态的?
在许多其他问题中,每个人都说对象必须是readonly
.我没有找到原因 - 即使在MSDN或JavaDoc中也没有.
由于我经常使用这种结构,有人可以向我解释我为什么要使用它readonly
?
谢谢!
Den*_*nis 56
如果我想确保它将被锁定我的应用程序中的所有线程:
如果锁定对象锁定对静态的访问,则该锁定对象必须是静态的.
否则它必须是实例,因为不需要锁定一个类实例的状态,并阻止其他线程同时使用另一个类实例.
每个人都说对象必须是"只读"我没有找到原因
那么,它并不必须是.这只是一种最佳做法,可以帮助您避免错误.
考虑以下代码:
class MyClass
{
private object myLock = new object();
private int state;
public void Method1()
{
lock (myLock)
{
state = // ...
}
}
public void Method2()
{
myLock = new object();
lock (myLock)
{
state = // ...
}
}
}
Run Code Online (Sandbox Code Playgroud)
这里Thread1可以获取锁定Method1
,但是要执行的Thread2 Method2
将忽略此锁定,因为锁定对象已更改=>状态可能已损坏.
Kae*_*ber 11
我想这意味着"引用锁定对象的变量应该只读".
您锁定变量引用的锁定对象,而不是变量本身.即
private object Locker = new object();
Run Code Online (Sandbox Code Playgroud)
你锁定了那个新对象(),而不是Locker字段.然后,如果你用另一个对象的引用替换字段的值,比如说
Locker = new object();
Run Code Online (Sandbox Code Playgroud)
并锁定它,你锁定了两个不同的对象,这违背了锁定的目的,因为你现在没有获得同步访问.
理想情况下,对象应该只读,以便不能将其更改为指向另一个对象.如果您对一个对象进行了锁定,那么另一个线程会更改该对象,如果,然后另一个线程出现,并尝试对该对象进行锁定,则该对象将不相同,因此原始锁定将是无效.
这将是一个非常罕见的情况.但是如果你对该对象有一个锁定,而另一个线程在该对象上等待,如果锁定线程调用Monitor.Pulse,则等待的线程被唤醒,并且可以对该对象进行锁定.在被唤醒和获取锁定之间的那段时间内,另一个线程可以更改锁中引用的对象,因此等待线程将锁定另一个对象.