在.net中,还可以使用Monitor实现线程并发同步。Monitor类是纯托管且完全可移植,并且可能会在操作系统资源需求方面更加高效。

Monitor的锁对象尽可能使用引用对象,如果是字符串或值对象,会出现引发SynchronizationLockException异常。

其实我们日常用的lock锁同步,其原理就是基于Monitor的。

即:

public static readonly object locker=new object();
lock(locker){
//to do something
}

和以下代码是一样的意思:

public static readonly object locker=new object();
try{
Monitor.Enter(locker); //to do something
}finally{
Monitor.Exit(locker);
}

以下是基于测试的代码:

        protected static readonly object _locker = new object();
[HttpGet("[controller]/api/[action]")]
public IActionResult Test()
{
int threadId = Thread.CurrentThread.ManagedThreadId;
ResponseModel rc = new ResponseModel(, $"{threadId} 初始化"); try
{
//独占资源锁
Monitor.Enter(_locker); int count = RedisHelper.GetAsync(RTestKey).Result.ToInt32();
if (count > )
{
if (RedisHelper.SetAsync(RTestKey, "-1").Result)
rc.SetMessage($"{threadId} 设置成功!");
}
else rc.SetMessage($"{threadId} 已被设置,不能再次设置!");
}
catch (Exception ex)
{
_log.Error(ex);
}
finally
{
//释放锁,让其他线程获取锁并进入该方法
Monitor.Exit(_locker);
} return Json(rc);
}

接下来通过测试程序连续发送8次请求,看看结果:

通过以上操作,证明可以使用Monitor实现多线程的并发同步操作。

如果在执行了Monitor.Enter(locker)之后,需要释放锁对象并阻塞当前线程,让其他线程获取锁并执行的话,可以使用Monitor.Wait()方法。Monitor.Wait()方法的作用就是释放当前线程持有的锁,让当前线程进入等待队列,让其他某个线程获取锁对象并进入就绪状态并执行。其他线程执行Monitor.Pulse或PulseAll方法之后,当前等待的线程就可以继续获取锁并进入就绪队列去执行。

Monitor的Wait、Pulse和PulseAll方法必须在Enter和Exit方法之间调用。

如下测试代码:

        static void Func1() {
Monitor.Enter(_locker);
for(int i = ; i < ; i++)
{
Console.Write($"=>Func1【{i}】");
Monitor.Pulse(_locker);
Monitor.Wait(_locker);
} Monitor.Exit(_locker);
} static void Func2()
{
Monitor.Enter(_locker);
for (int i = ; i < ; i++)
{
Monitor.Wait(_locker);
Console.Write($"=>Func2【{i}】");
Monitor.Pulse(_locker);
} Monitor.Exit(_locker);
} static void Func4() {
List<Task> list = new List<Task>{
Task.Factory.StartNew(Func1),
Task.Factory.StartNew(Func2)
}; Task.WaitAll(list.ToArray());
} public static readonly object _locker = new object();
static void Main(string[] args)
{
Func4();
}

这段代码的目的是Fun1函数执行一次后,Fun2函数再执行一次,依次循环。让我们看看执行的结果:

由此看来,达到了本次测试的目的。

.net core WebApi Monitor实现并发同步的更多相关文章

  1. .net core WebApi ManualResetEvent实现并发同步

    ManualResetEvent,即手动重置事件,通过信号量来判别当前线程是否应该阻塞或继续执行.使用方式与ManualResetEventSlim差不多,ManualResetEventSlim只是 ...

  2. .net core WebApi Mutex实现并发同步

    Mutex,中文译为互斥体,在.net中也是作为一种线程或进程之间的互斥体存在.即在同一时刻,一个共享资源只允许被某一个线程或进程访问,其他线程或进程需要等待(直至获取互斥锁为止). Mutex的使用 ...

  3. .Net Core WebAPI 基于Task的同步&异步编程快速入门

    .Net Core WebAPI 基于Task的同步&异步编程快速入门 Task.Result async & await 总结 并行任务(Task)以及基于Task的异步编程(asy ...

  4. Net Core WebAPI

    Net Core WebAPI .Net Core WebAPI 基于Task的同步&异步编程快速入门 Task.Result async & await 总结 并行任务(Task)以 ...

  5. .net core WebApi Interlocked配合ManualResetEventSlim实现并发同步

    由于项目有某种需求,在WebApi中,有大量的请求需要操作相同的数据,因此需要用到并发同步机制去操作共享的数据. 本次配合使用Interlocked和ManualResetEventSlim来实现并发 ...

  6. 探索 Java 同步机制[Monitor Object 并发模式在 Java 同步机制中的实现]

    探索 Java 同步机制[Monitor Object 并发模式在 Java 同步机制中的实现] https://www.ibm.com/developerworks/cn/java/j-lo-syn ...

  7. net core WebApi——文件分片下载

    目录 前言 开始 测试 小结 @ 前言 上一篇net core WebApi--文件分片上传与跨域请求处理介绍完文件的上传操作,本来是打算紧接着写文件下载,中间让形形色色的事给耽误的,今天还是抽个空整 ...

  8. ASP.NET Core WebAPI控制器返回类型的最佳选项

    前言 从.NET Core 2.1版开始,到目前为止,控制器操作可以返回三种类型的WebApi响应.这三种类型都有自己的优点和缺点,但都缺乏满足REST和高可测性的选项. ASP.NET Core中可 ...

  9. ASP.NET Core WebApi使用Swagger生成api说明文档

    1. Swagger是什么? Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务.总体目标是使客户端和文件系统作为服务器以同样的速度来更新.文件 ...

随机推荐

  1. python列表常用内建方法

    python列表常用内建方法: abc = ['a',1,3,'a'] #abc.pop(1) #删除索引1的值.结果['a', 3] #abc.append([123]) #结果:['a', 1, ...

  2. Streaming从Spark2X迁移到Spark1.5 summary

    配置文件的加载是一个难点,在local模式下非常容易,但是submit后一直报找不到文件,后来采用将properties文件放在加载类同一个package下,打包到同一个jar中解决. import ...

  3. Array 转 Set

    Array 转 Set: Set<String> oldCandidateNames = new HashSet<String>(Arrays.asList(candidate ...

  4. BIOS备忘录之x86硬件编程(寄存器与IO)

    SOC固件(BIOS)开发: 1.熟悉硬件原理图:要弄清楚pin脚的功能: 2.配置GPIO引脚,配置成Native功能还是GPIO功能(如果是配置成GPIO,需要在code里面显式的使用): 3.硬 ...

  5. ipconfig/release时:系统找不到指定的文件。无法连接网络

    问题描述: ipconfig/release时:系统找不到指定的文件,无法连接网络,无法获取正确ip地址 处理方法: 修复Winsock和重置IP设置.第一步:开始-运行,输入cmd,打开命令行窗口. ...

  6. JavaScript Dom 事件

    JavaScript  Dom 事件 对于事件需要注意的要点: // this标签当前正在操作的标签. this // event封装了当前事件的内容. even 常用事件 // 鼠标单击.触发事件 ...

  7. Angular7 表单

    Angular 表单 input.checkbox.radio. select. textarea 实现在线预约功能 html 文件 <h2>人员登记系统</h2> <d ...

  8. Android一个工程引用另一个工程的方法

    一个工程包含另一个工程.相当于一个jar包的引用.但又不是jar包反而像个package 现在已经有了一个Android工程A.我们想扩展A的功能,但是不想在A的基础上做开发,于是新建了另外一个And ...

  9. Linux统计系统文件类型出现的次数

    awk '/^UUID/{fs[$3]++}END{for(i in fs) {print i,fs[i]}}' /etc/fstab /^UUID/ 匹配确定行范围

  10. SVN冲突以及解决办法

    1.冲突原因: 假设 A.B 两个用户都在版本号为 100 的时候,更新了 kingtuns.txt 这个文件,A 用户在修改完成之后提交 kingtuns.txt 到服务器, 这个时候提交成功,这个 ...