C# lock线程锁的用法

 更新时间:2023年11月01日 09:18:54   作者:大花爱编程  
在C#中,锁lock是一种同步机制,允许在同一时间只允许一个线程访问指定的代码或区域,本文主要介绍了C# lock线程锁的用法,具有一定的参考价值,感兴趣的可以了解一下

一、lock的作用

Lock可以看成在操作系统中的临界区,Lock区域内的代码表示临界区,使得同一时间只有一个线程能够进入Lock所包含的函数中,实现原子操作,保护同一资源只有一个线程进行修改,实现不同线程中数据的同步。

未进入Lock的线程将被阻塞等待,直到Lock锁被打开才唤醒其中一个进入,并且进行上锁
总的来说Lock在多线程的运行中可以保证数据安全,对于保护的区域只允许一个线程使用!

二、lock的基础使用

  private  Object thisLock = new Object();//创建对象锁
  或者
  private static readonly object thisLock = new object();
    lock (thisLock)
   {   
         // Critical code section
    }

注意事项:

  • 需要注意的是首先创建的对象锁,应该是不同线程能够访问的同一个对象,因此至少应该是在类中是全局的,不应为局部变量。
  • 为了实现全局的对象锁,可以使用static,例:private  static Object thisLock = new Object();//创建对象锁
  • 结合自己线程的运行特性,选择正确的对象锁

三、lock(this)的用法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Lock测试
{
    class Program
    {
        static void Main(string[] args)
        {
            C1 c1 = new C1();

            //在t1线程中调用LockMe,并将deadlock设为true(将出现死锁)
            Thread t1 = new Thread(c1.LockMe);
            t1.Start(true);
            Thread.Sleep(100);

            //在主线程中lock c1
            lock (c1)
            {
                //调用没有被lock的方法
                c1.DoNotLockMe();
                //调用被lock的方法,并试图将deadlock解除
                c1.LockMe(false);
            }
            Console.Read();
        }

    }
    class C1
    {
        private bool deadlocked = true;

        //这个方法用到了lock,我们希望lock的代码在同一时刻只能由一个线程访问
        public void LockMe(object o)
        {
            lock (this)
            {
                while (deadlocked)
                {
                    deadlocked = (bool)o;
                    Console.WriteLine("Foo: I am locked :("+o);
                    Thread.Sleep(500);
                }
            }
        }

        //所有线程都可以同时访问的方法
        public void DoNotLockMe()
        {
            Console.WriteLine("I am not locked :)");
        }
    }
}

在这个代码中,出现了两个lock锁,在C1中有一个锁,lock(this)主要是对LockMe方法进行上锁,在主要线程中又有一个Lock锁,主要是Lock(c1),该代码中,lock(this)其实就是把C1的实例c1当钥匙拿走,导致主线程后的lock(c1)无法继续执行。

当我们将lock的钥匙修改,如下:

       private bool deadlocked = true;
        private object locker = new object();

        //这个方法用到了lock,我们希望lock的代码在同一时刻只能由一个线程访问
        public void LockMe(object o)
        {
            lock (locker)
            {
                while (deadlocked)
                {
                    deadlocked = (bool)o;
                    Console.WriteLine("Foo: I am locked :("+o);
                    Thread.Sleep(500);
                }
            }
        }

        //所有线程都可以同时访问的方法
        public void DoNotLockMe()
        {
            Console.WriteLine("I am not locked :)");
        }
    }
}

我们可以发现,就可以继续执行

总结:

1. lock(this)的缺点就是在一个线程(例如本例的t1)通过执行该类的某个使用"lock(this)"的方法(例如本例的LockMe())锁定某对象之后, 导致整个对象无法被其他线程(例如本例的主线程)访问 - 因为很多人在其他线程(例如本例的主线程)中使用该类的时候会使用类似lock(c1)的代码。
2. 锁定的不仅仅是lock段里的代码,锁本身也是线程安全的。
3. 我们应该使用不影响其他操作的私有对象作为locker。
4. 在使用lock的时候,被lock的对象(locker)一定要是引用类型的,如果是值类型,将导致每次lock的时候都会将该对象装箱为一个新的引用对象(事实上如果使用值类型,C#编译器(3.5.30729.1)在编译时就会给出一个错误)。

参考文献:

关于lock(this)的说明及用法-CSDN博客

C# 关于线程锁lock的使用方法_c# lock方法-CSDN博客

C#线程锁(Lock)_c# lock_月光在发光的博客-CSDN博客

到此这篇关于C# lock线程锁的用法的文章就介绍到这了,更多相关C# lock线程锁 内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C#中事件处理的个人体会

    C#中事件处理的个人体会

    C#中事件处理的个人体会...
    2007-03-03
  • Dictionary扩展基础类向字典中添加键和值

    Dictionary扩展基础类向字典中添加键和值

    Dictionary<TKey, TValue> 类是常用的一个基础类,但用起来有时确不是很方便。本文逐一讨论,并使用扩展方法解决
    2013-11-11
  • WinForm实现自定义右下角提示效果的方法

    WinForm实现自定义右下角提示效果的方法

    这篇文章主要介绍了WinForm实现自定义右下角提示效果的方法,涉及WinForm自定义提示效果的实现方法,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-08-08
  • asp.net中XML如何做增删改查操作

    asp.net中XML如何做增删改查操作

    工作之余,温习一下对xml的简单操作,抽个时间把asp.net XML增删改查操作方法分享给大家,需要的朋友可以参考下
    2015-08-08
  • 基于多态之虚方法、抽象类、接口详解

    基于多态之虚方法、抽象类、接口详解

    下面小编就为大家分享一篇基于多态之虚方法、抽象类、接口详解,具有很好的参考价值。希望对大家有所帮助。一起跟随小编过来看看吧
    2017-11-11
  • 详解LINQ入门(上篇)

    详解LINQ入门(上篇)

    这篇文章主要介绍了详解LINQ入门(上篇),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-12-12
  • C#将Excel转成PDF的方法

    C#将Excel转成PDF的方法

    今天小编就为大家分享一篇关于C#将Excel转成PDF的方法,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • C#实现图片放大功能的按照像素放大图像方法

    C#实现图片放大功能的按照像素放大图像方法

    这篇文章主要介绍了C#实现图片放大功能的按照像素放大图像方法,功能非常实用,需要的朋友可以参考下
    2014-07-07
  • C#实现上传下载图片

    C#实现上传下载图片

    这篇文章主要为大家详细介绍了C#实现上传下载图片功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-07-07
  • C#生成指定范围内的不重复随机数

    C#生成指定范围内的不重复随机数

    对于随机数,大家都知道,计算机不 可能产生完全随机的数字,所谓的随机数发生器都是通过一定的算法对事先选定的随机种子做复杂的运算,用产生的结果来近似的模拟完全随机数,这种随机数被称 作伪随机数。伪随机数是以相同的概率从一组有限的数字中选取的。
    2015-05-05

最新评论