C#lock关键字的用法 [英] Usage of the C# lock keyword

查看:134
本文介绍了C#lock关键字的用法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对C#锁的理解如下,请帮助我验证我是否正确.

I post my understanding of C# lock as follows, please help me validate whether or not I get it right.

public class TestLock
{
    private object threadLock = new object();
    ...
    public void PrintOne()
    {
        lock (threadLock)
        {
            // SectionOne
        }
    }

    public void PrintTwo()
    {
        lock (threadLock)
        {
            // SectionTwo
        }
    }
    ...
}

案例1> Thread1和Thread2同时尝试调用PrintOne. 由于PrintOne受到实例锁的保护,因此在任何时候都只能 一个线程可以独占进入SectionOne.

Case I> Thread1 and Thread2 simultaneously try to call PrintOne. Since PrintOne is guarded by the instance lock, at any time, only one thread can exclusively enter the SectionOne.

这正确吗?

第二种情况> 线程1和线程2同时尝试调用PrintOne和PrintTwo 分别(即Thread1调用PrintOne和Thread2调用PrintTwo) 由于两种打印方法均由同一个实例锁保护,因此在任何时候, 只有一个线程可以独占访问SectionOne或SectionTwo,但不能同时访问这两个线程.

Case II> Thread1 and Thread2 simultaneously try to call PrintOne and PrintTwo respectively (i.e. Thread1 calls PrintOne and Thread2 calls PrintTwo) Since two print methods are guarded by the same instance lock, at any time, only one thread can exclusively access either SectionOne or SectionTwo, but NOT both.

这正确吗?

推荐答案

1和2仅 true .如果他们使用不同的实例,则两种情况均为 false

1 and 2 are true only if all your threads use the same instance of the class. If they use different instances, then both cases are false

样品

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
    }
}

一种可能的解决方案是在锁定对象声明和使用它的方法中添加一个静态关键字.

One of the possible solutions is to add a static keyword to the locking object declaration and methods that use it.

private  static object threadLock = new object();

更新 konrad.kruczynski提出的要点

UPDATE Good point made by konrad.kruczynski

...线程安全"也假定为 语境.例如,我可以 您的文件打开代码以及 生成带有静态锁的异常- 只是接受另一个申请 领域.因此建议 应该使用系统范围内的Mutex类或 那样因此静态情况 只是被推断为实例之一.

..."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#lock关键字的用法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆