如何解决C#锁定关键字
我对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。
它是否正确?
情况二>线程1和线程2同时尝试调用PrintOne和PrintTwo
分别(即Thread1调用PrintOne和Thread2调用PrintTwo)
由于两种打印方法均由同一实例锁保护,因此,
只有一个线程可以独占访问SectionOne或SectionTwo,但不能同时访问这两个线程。
它是否正确?
解决方法
仅当所有线程都使用该类的相同实例时,1和2才为true。如果他们使用不同的实例,则两种情况都为假
样品
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
}
}
一种可能的解决方案是在锁定对象声明和使用它的方法中添加一个静态关键字。
private static object threadLock = new object();
更新
konrad.kruczynski提出的要点
... \“线程安全\”也假定为
上下文。例如,我可以
您的文件打开代码以及
使用静态锁生成异常-
只是接受另一个申请
域。因此建议
应该使用系统范围内的Mutex类或
那样因此静态情况
只是被推论为实例之一。
, 是的,是的。情况是正确的。
, 您的理解是100%正确的。因此,例如,如果您想允许分别进入这两种方法,则需要两个锁。
, 案例一:检查✓
情况二:检查✓
不要忘记,锁定只是线程同步的一种方法。有关其他用户完整方法,请阅读:线程同步
直接来自MSDN示例:
public class TestThreading
{
private System.Object lockThis = new System.Object();
public void Process()
{
lock (lockThis)
{
// Access thread-sensitive resources.
}
}
}
, 是的,您在两个方面都是正确的。
, 这是基本知识(或多或少)
1)对实例数据使用实例锁
public class InstanceOnlyClass{
private int callCount;
private object lockObject = new object();
public void CallMe()
{
lock(lockObject)
{
callCount++;
}
}
}
2)对静态数据使用静态锁
public class StaticOnlyClass{
private int createdObjects;
private static object staticLockObject = new object();
public StaticOnlyClass()
{
lock(staticLockObject)
{
createdObjects++;
}
}
}
3)如果您要保护静态和实例数据,请使用单独的静态和实例锁
public class StaticAndInstanceClass{
private int createdObjects;
private static object staticLockObject = new object();
private int callCount;
private object lockObject = new object();
public StaticAndInstanceClass()
{
lock(staticLockObject)
{
createdObjects++;
}
}
public void CallMe()
{
lock(lockObject)
{
callCount++;
}
}
}
基于此,如果您访问实例数据,则代码很好,但是如果您修改静态数据,则代码不安全
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。