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#使用NPOI对Excel数据进行导入导出

    C#使用NPOI对Excel数据进行导入导出

    这篇文章介绍了C#使用NPOI对Excel数据进行导入导出的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06
  • C# Csv实现基本的读写和转换DataTable

    C# Csv实现基本的读写和转换DataTable

    本文主要介绍了C# Csv实现基本的读写和转换DataTable,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-02-02
  • 超炫酷的WPF实现Loading控件效果

    超炫酷的WPF实现Loading控件效果

    这篇文章主要介绍了超炫酷的WPF实现Loading控件效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2015-11-11
  • C#中使用闭包与意想不到的坑详解

    C#中使用闭包与意想不到的坑详解

    这篇文章主要给大家介绍了关于C#中使用闭包与意想不到的坑,文中通过示例代码介绍的非常详细,对大家学习或者使用C#具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2020-06-06
  • C#在无Office环境中实现Word文档转图片的方法

    C#在无Office环境中实现Word文档转图片的方法

    在C#项目开发中,你是否曾遇到过这样的场景:需要将Word文档内容以图片形式展示在网页上、生成文档缩略图、在无Office环境的服务器上预览文档,本文将旨在帮助C#开发者实现在无Office环境中高效实现Word文档转图片,需要的朋友可以参考下
    2025-08-08
  • WPF中实现单例窗口的解决方案

    WPF中实现单例窗口的解决方案

    在WPF企业级应用开发中,我们常常需要确保某个窗口在同一时间只能有一个实例存在,同时还需要支持窗口的关联关闭,在这里,我们实现线程安全的单例窗口管理、完善的父子窗口生命周期控制以及灵活的参数化窗口构造,为WPF应用提供一套健壮的窗口管理解决方案
    2025-08-08
  • C#绘制柱状图和折线图的方法

    C#绘制柱状图和折线图的方法

    这篇文章主要为大家详细介绍了C#绘制柱状图和折线图的方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • C#中让控件全屏显示的实现代码(WinForm)

    C#中让控件全屏显示的实现代码(WinForm)

    有时候需要让窗口中某一块的内容全屏显示,比如视频播放、地图等等。经过摸索,暂时发现两种可行方法,如果有谁知道其他方法,敬请告知
    2012-04-04
  • C#中设计、使用Fluent API

    C#中设计、使用Fluent API

    这篇文章主要介绍了C#中设计、使用Fluent API,本文讲解了最简单且最实用的设计、设计具有调用顺序的Fluent API、泛型类的Fluent设计等内容,需要的朋友可以参考下
    2015-03-03
  • c#检测端口是否被占用的简单实例

    c#检测端口是否被占用的简单实例

    这篇文章主要介绍了c#检测端口是否被占用的简单实例,有需要的朋友可以参考一下
    2013-12-12

最新评论