我贴出我对C#锁的理解如下,请大家帮我验证一下是否正确。
public class TestLock
{
private object threadLock = new object();
...
public void PrintOne()
{
lock (threadLock)
{
// SectionOne
}
}
public void PrintTwo()
{
lock (threadLock)
{
// SectionTwo
}
}
...
}
案例 I> Thread1 和 Thread2 同时尝试调用 PrintOne。 由于 PrintOne 由实例锁保护,因此在任何时候,只有 一个线程可以独占进入SectionOne。
这是正确的吗?
案例二> Thread1 和 Thread2 同时尝试调用 PrintOne 和 PrintTwo 分别(即 Thread1 调用 PrintOne 和 Thread2 调用 PrintTwo) 由于两个打印方法由同一个实例锁保护,在任何时候, 只有一个线程可以独占访问 SectionOne 或 SectionTwo,但不能同时访问两者。
这是正确的吗?
最佳答案
如果所有线程都使用类的相同实例,则 1 和 2 仅为真。如果他们使用不同的实例,那么这两种情况都是假
示例
public class TestLock
{
private object threadLock = new object();
public void PrintOne()
{
lock (threadLock)
{
Console.WriteLine("One");
var f = File.OpenWrite(@"C:\temp\file.txt"); //same static resource
f.Close();
}
}
public void PrintTwo()
{
lock (threadLock)
{
Console.WriteLine("Two");
var f = File.OpenWrite(@"C:\temp\file.txt"); //same static resource
f.Close();
}
}
}
和测试代码
static void Main(string[] args)
{
int caseNumber = 100;
var threads = new Thread[caseNumber];
for (int i = 0; i < caseNumber; i++)
{
var t = new Thread(() =>
{
//create new instance
var testLock = new TestLock();
//for this instance we safe
testLock.PrintOne();
testLock.PrintTwo();
});
t.Start();
//once created more than one thread, we are unsafe
}
}
一种可能的解决方案是在锁定对象声明和使用它的方法中添加一个 static 关键字。
private static object threadLock = new object();
更新 konrad.kruczynski 提出的要点
..."thread safety" is also assumed from context. For example, I could take your file opening code and also generate exception with static lock - just taking another application domain. And therefore propose that OP should use system-wide Mutex class or sth like that. Therefore static case is just inferred as the instance one.
关于c# - C# lock 关键字的使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6157752/