在.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. 使用Chrome远程调试GenyMotion上的WebView程序

    WebView让我们方便的使用熟悉的Html/JS/Css来开发APP.但是,当出现问题时,却没有PC上那么方便的排查问题.PC上,前端的问题我们可以使用Chrome的开发者工具方便的调试.Andro ...

  2. Centos 忘记root密码怎么办?

    1 - 在启动grub菜单,选择编辑选项启动 2 - 按键盘e键,来进入编辑界面 3 - 找到Linux 16的那一行,将ro改为rw init=/sysroot/bin/sh 4 - 现在按下 Co ...

  3. java中的key事件监听机制

    package com.at221; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import javax.sw ...

  4. Java的反射机制的详细应用

    package com.at221; import java.io.Serializable; import java.lang.reflect.*; import org.junit.Test; p ...

  5. tensorflow变量

    tensorflow变量: 1.神经网络中的参数权重,偏置等可以作为张量保存到tensorflow的变量中 2.tensorflow变量必须被初始化 3.可被保存到文件中,下次使用重新加载即可 ten ...

  6. q次询问,每次给一个x,问1到x的因数个数的和。

    q次询问,每次给一个x,问1到x的因数个数的和. #include<cmath> #include<cstdio> #include<cstring> usingn ...

  7. 《CSS世界》读书笔记(六)

    <!-- <CSS世界> 张鑫旭著 --> min-width/max-width和min-height/max-height min-width/max-width出现的场景 ...

  8. 盒子布局、标签特性display、浮动、定位position

    盒子模型布局: 盒子模型:每个标签都是一个盒子 盒子在页面显示在大小是:自身宽度+边框+边距(内边框+外边距) 如果一个盒子设置了边框,则边框需要被加两遍.若果设置了边距则内外边距根据设置情况要被加两 ...

  9. Eclipse进度条出现“Remote System Explorer Operation”解决方法

    Eclipse进度条出现“Remote System Explorer Operation”解决方法  

  10. Docker Kubernetes Service 代理服务创建

    Docker Kubernetes  Service 代理服务创建 创建Service需要提前创建好pod容器.再创建Service时需要指定Pod标签,它会提供一个暴露端口默会分配容器内网访问的唯一 ...