q09*_*987 8 c# multithreading locking
我发布了对C#lock的理解如下,请帮助我验证我是否正确.
public class TestLock
{
private object threadLock = new object();
...
public void PrintOne()
{
lock (threadLock)
{
// SectionOne
}
}
public void PrintTwo()
{
lock (threadLock)
{
// SectionTwo
}
}
...
}
Run Code Online (Sandbox Code Playgroud)
案例I> Thread1和Thread2同时尝试调用PrintOne.由于PrintOne受到实例锁的保护,因此任何时候只有一个线程可以独占进入SectionOne.
它是否正确?
案例II> 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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
并测试代码
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
}
}
Run Code Online (Sandbox Code Playgroud)
一种可能的解决方案是向锁定对象声明和使用它的方法添加一个static关键字.
private static object threadLock = new object();
Run Code Online (Sandbox Code Playgroud)
更新 konrad.kruczynski提出的好点
......"线程安全"也是从上下文中假设的.例如,我可以使用您的文件打开代码并使用静态锁生成异常 - 只需要另一个应用程序域.因此建议OP应该使用系统范围的Mutex类或类似的那样.因此静态情况只是推断为实例一.
| 归档时间: |
|
| 查看次数: |
4514 次 |
| 最近记录: |