一、自旋锁

自旋锁是指当一个线程在获取锁对象的时候,如果锁已经被其它线程获取,那么这个线程将会循环等待,不断的去获取锁,直到获取到了锁。适合于原子操作时间非常短的场景

优点:避免了线程上下文切换。性能较高。

缺点:如果长时间等待,将消耗大量的CPU资源。而且多个等待中的线程,并不是等待时间越长就先获取到锁,可能会一直等待下去。

两种实现方式如下:

实现代码一:

private static int _SpinLock = 0;//锁对象
private static int incrValue = 0;//共享资源
private void Run()
{//获取锁//使用int原子操作将_SpinLock的值赋值为1,Interlocked.Exchange(ref _SpinLock, 1)的返回值为改变之前的值。//如果返回0,则获取到了锁, 如果返回1,则锁被占用while (Interlocked.Exchange(ref _SpinLock, 1) != 0){Thread.SpinWait(1);//自旋锁等待}incrValue++;  //安全的逻辑计算//释放锁:将_SpinLock重置会0;Interlocked.Exchange(ref _SpinLock, 0);
}[HttpGet]
public async Task<string> Get()
{Parallel.For(0, 1000, (i) =>{Run();});Console.WriteLine($"incrValue={incrValue}");
}

实现代码二:

private static SpinLock _spinLock = new SpinLock();
private static int incrValue = 0;//共享资源
private void Run()
{bool locked = false;_spinLock.Enter(ref locked);//获取锁incrValue++;  //安全的逻辑计算if (locked) //释放锁_spinLock.Exit();
}
[HttpGet]
public async Task<string> Get()
{Parallel.For(0, 1000, (i) =>{Run();});Console.WriteLine($"incrValue={incrValue}");
}

二、互斥锁

互斥锁是基于原子操作和线程调度实现的;当一个线程在获取锁对象的时候,如果锁已经被其它线程获取,那么这个线程不会循环获取锁,它会进入等待状态,等待被唤醒。适用于等待时间较长和跨进程的场景。

互斥锁支持重入(当一个线程获取到锁之后,中间的代码可以再次获取锁。适用于多个函数调用。获取锁的次数必须等于释放锁的次数)。

互斥锁支持跨进程共享;多个进程之间使用同一个互斥锁。

实现代码如下:

private static readonly Mutex _mutexLock = new Mutex();
private static int incrValue = 0;//共享资源
private void Run()
{_mutexLock.WaitOne();//获取锁try{incrValue++;  //安全的逻辑计算}finally {_mutexLock.ReleaseMutex();//释放锁}
}[HttpGet]
public async Task<string> Get()
{Parallel.For(0, 1000, (i) =>{Run();});Console.WriteLine($"incrValue={incrValue}");
}

三、混合锁

混合锁混合了自旋锁和互斥锁。刚开始会像自旋锁一样,先重试一定的次数;超过这个次数之后将线程设置为等待状态。

混合锁适用于大多数场景。

实现代码一:

 private static readonly object _monitorLock = new object();private static int incrValue = 0;//共享资源private void Run(){var islocked = false;try{Monitor.Enter(_monitorLock, ref islocked);  //获取锁incrValue++;  //安全的逻辑计算}finally {if(islocked) Monitor.Exit(_monitorLock);// 释放锁}}[HttpGet]public async Task<string> Get(){Parallel.For(0, 1000, (i) =>{Run();});Console.WriteLine($"incrValue={incrValue}");
}

实现代码二:

private static readonly object _monitorLock = new object();
private static int incrValue = 0;//共享资源
private void Run()
{lock (_monitorLock){incrValue++;  //安全的逻辑计算}
}[HttpGet]
public async Task<string> Get()
{Parallel.For(0, 1000, (i) =>{Run();});Console.WriteLine($"incrValue={incrValue}");
}

C#线程锁(自旋锁SpinLock、互斥锁Mutex、混合锁Monitor | lock)相关推荐

  1. C#线程同步(3)- 互斥量 Mutex

    什么是Mutex "mutex"是术语"互相排斥(mutually exclusive)"的简写形式,也就是互斥量.互斥量跟临界区中提到的Monitor很相似, ...

  2. Linux并发与竞争介绍(原子操作、自旋锁、信号量、互斥体)

    目录 并发与竞争 并发与竞争简介 保护内容是什么 原子操作 原子操作简介 原子整形操作API函数(atomic_t 结构体) 原子位操作API 函数 自旋锁 自旋锁简介 自旋锁API函数 线程与线程 ...

  3. C# lock 语法糖实现原理--《.NET Core 底层入门》之自旋锁,互斥锁,混合锁,读写锁...

    在多线程环境中,多个线程可能会同时访问同一个资源,为了避免访问发生冲突,可以根据访问的复杂程度采取不同的措施 原子操作适用于简单的单个操作,无锁算法适用于相对简单的一连串操作,而线程锁适用于复杂的一连 ...

  4. Linux内核中的同步原语:自旋锁,信号量,互斥锁,读写信号量,顺序锁

    Linux内核中的同步原语 自旋锁,信号量,互斥锁,读写信号量,顺序锁 rtoax 2021年3月 在英文原文基础上,针对中文译文增加5.10.13内核源码相关内容. 1. Linux 内核中的同步原 ...

  5. 自旋锁:pthread_spinlock_t,互斥锁:pthread_mutex_t,条件变量:pthread_cond_t,读写锁:pthread_rwlock_t

    Table of Contents pthread提供的锁 互斥锁 自旋锁 pthreadtypes.h    nptl\sysdeps\unix\sysv\linux\i386\bits    44 ...

  6. 互斥锁(排它锁、独占锁、写锁、X锁)和共享锁(读锁、S锁) 自旋锁

    共享锁(S锁):如果事务T对数据A加上共享锁后,则其他事务只能对A再加共享锁,不能加排他锁,直到已释放所有共享锁.获准共享锁的事务只能读数据,不能修改数据. 排他锁(X锁):如果事务T对数据A加上排他 ...

  7. POSIX互斥锁自旋锁

    基础组件-POSIX互斥锁自旋锁 基础组件 基础组件-POSIX互斥锁自旋锁 前言 一.互斥锁 二.自旋锁 特点: 场景: 使用原则 自旋锁属性 三.两把锁的区别 1. 调度策略 2.使用场景 四.常 ...

  8. 什么是自旋锁+自旋锁和互斥锁的区别

    文章目录 本文链接 什么是自旋锁 参考链接 自旋锁和互斥锁的区别 参考链接 本文链接 击打 什么是自旋锁 多线程对共享资源访问, 为防止并发引起的相关问题, 常引入锁的机制来处理并发问题.   获取到 ...

  9. java锁(公平锁和非公平锁、可重入锁(又名递归锁)、自旋锁、独占锁(写)/共享锁(读)/互斥锁、读写锁)

    前言 本文对Java的一些锁的概念和实现做个整理,涉及:公平锁和非公平锁.可重入锁(又名递归锁).自旋锁.独占锁(写)/共享锁(读)/互斥锁.读写锁 公平锁和非公平锁 概念 公平锁是指多个线程按照申请 ...

最新文章

  1. Linux下redis的安装(适用centos)
  2. python人脸识别项目_基于Python与命令行人脸识别项目(系列二)
  3. Qt Creator管理会议
  4. php图片上传方案,php图片上传
  5. 典型电商网站的站点导航的布局结构实现,及运用三种方式实现下拉效果
  6. JavaScript高阶函数快速入门
  7. mysql 创建和删除库_mysql入门系列:mysql创建、删除和选择数据库
  8. 2950交换机简明配置维护手册
  9. pid算法matlab仿真程序和c程序,pid算法matlab仿真程序和c程序.doc
  10. 立于山巅!他,凭什么抗住万亿级流量冲击!
  11. redisconnectionfactory 没有这个bean_浅析Spring中bean的作用域
  12. mysql 数据备份 crontab
  13. 信号计算机联锁试题,计算机联锁试题.doc
  14. 单片机(ISIS 7 Professional):简易0~7数字键盘代码项目
  15. sumif单列求和_有关多列条件求和对30列数据条件求和的快速SUMIF公式
  16. 你听过“费斯汀格法则”吗?多少人因为不懂而被残害!好文!
  17. Linux系统分区备份工具,linux系统备份工具:clonezilla
  18. java 给图片加水印整理:2种方法
  19. 计算机如何磁盘整理,如何整理磁盘碎片让Win7电脑运行更快?
  20. 绘画教程:如何轻松画出皮肤的挤压感

热门文章

  1. 在初始化安装时发生异常: System.BadImageFormatException: 未能加载文件或程序集
  2. 时间复杂度O(n * log n)之快速排序法
  3. yum如何安装特定版本的gcc_yum安装gcc
  4. 【Unity】遍历一个物体的子物体的三种方法
  5. 今年五一小长假“长途游”“跨省游”或将迎来一波强劲反弹
  6. C++进阶(语法篇)—第11章 设计模式(3)
  7. 人生苦短,我用PyCharm
  8. JS三元表达式多条件写法
  9. 转换CAJ到PDF:教你如何将CAJ文件转成PDF文件
  10. matlab ‘%6.2f %12.8f ‘ 是什么意思