C#读写锁ReaderWriterLockSlim的使用

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks; namespace ReaderWriteLockExercise
{
class Program
{
static private ReaderWriterLockSlim rwl = new ReaderWriterLockSlim();//读写锁
static void Main(string[] args)
{
//当某个线程进入读取模式时,此时其他线程依然能进入读取模式,假设此时一个线程要进入写入模式,那么他不得不被阻塞。直到读取模式退出为止。
Task t_read1 = new Task(ReadSomething);
t_read1.Start();
Console.WriteLine("{0} Create Thread ID {1} , Start ReadSomething", DateTime.Now.ToString("hh:mm:ss fff"), t_read1.GetHashCode());
Task t_read2 = new Task(ReadSomething);
t_read2.Start();
Console.WriteLine("{0} Create Thread ID {1} , Start ReadSomething", DateTime.Now.ToString("hh:mm:ss fff"), t_read2.GetHashCode());
//如果某个线程进入了写入模式,那么其他线程无论是要写入还是读取,都是会被阻塞的
Task t_write1 = new Task( WriteSomething);
t_write1.Start();
Console.WriteLine("{0} Create Thread ID {1} , Start WriteSomething", DateTime.Now.ToString("hh:mm:ss fff"), t_write1.GetHashCode());
Console.ReadKey();
}
static public void ReadSomething()
{
Console.WriteLine("*************************************读取模式*********************************************");
Console.WriteLine("{0} Thread ID {1} Begin EnterReadLock...", DateTime.Now.ToString("hh:mm:ss fff"), Task.CurrentId.GetHashCode());
rwl.EnterReadLock();//进入读取模式锁定状态
try
{
Console.WriteLine("{0} Thread ID {1} reading sth...", DateTime.Now.ToString("hh:mm:ss fff"), Task.CurrentId.GetHashCode());
Thread.Sleep(5000);//模拟读取信息
Console.WriteLine("{0} Thread ID {1} reading end.", DateTime.Now.ToString("hh:mm:ss fff"), Task.CurrentId.GetHashCode());
}
finally
{
rwl.ExitReadLock();
Console.WriteLine("{0} Thread ID {1} ExitReadLock...", DateTime.Now.ToString("hh:mm:ss fff"), Task.CurrentId.GetHashCode());
}
}
static public void WriteSomething()
{
Console.WriteLine("***********************************写入模式***************************************************");
Console.WriteLine("{0} Thread ID {1} Begin EnterWriteLock...", DateTime.Now.ToString("hh:mm:ss fff"), Task.CurrentId.GetHashCode());
rwl.EnterWriteLock();//进入写入模式锁定状态
try
{
Console.WriteLine("{0} Thread ID {1} writing sth...", DateTime.Now.ToString("hh:mm:ss fff"), Task.CurrentId.GetHashCode());
Thread.Sleep(10000);//模拟写入信息
Console.WriteLine("{0} Thread ID {1} writing end.", DateTime.Now.ToString("hh:mm:ss fff"), Task.CurrentId.GetHashCode());
}
finally
{
rwl.ExitWriteLock();
Console.WriteLine("{0} Thread ID {1} ExitWriteLock...", DateTime.Now.ToString("hh:mm:ss fff"), Task.CurrentId.GetHashCode());
}
}
}
}

输出结果

02:08:48 270 Create Thread ID 3888474 , Start ReadSomething
02:08:48 341 Create Thread ID 25209742 , Start ReadSomething
02:08:48 341 Create Thread ID 26966483 , Start WriteSomething
*************************************读取模式*********************************************
02:08:48 416 Thread ID 1 Begin EnterReadLock...
*************************************读取模式*********************************************
02:08:48 417 Thread ID 2 Begin EnterReadLock...
02:08:48 417 Thread ID 1 reading sth...
02:08:48 417 Thread ID 2 reading sth...
***********************************写入模式***************************************************
02:08:48 506 Thread ID 3 Begin EnterWriteLock...
02:08:53 419 Thread ID 2 reading end.
02:08:53 419 Thread ID 2 ExitReadLock...
02:08:53 419 Thread ID 1 reading end.
02:08:53 420 Thread ID 1 ExitReadLock...
02:08:53 420 Thread ID 3 writing sth...
02:09:03 422 Thread ID 3 writing end.
02:09:03 422 Thread ID 3 ExitWriteLock...

可以看到1号线程和2号线程读取,3号线程5秒后,也就是1和2号线程结束读取模式之后,3号线程开始进入写入模式。

如果将写入线程加到两个,并放在读取线程的前面,如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks; namespace ReaderWriteLockExercise
{
class Program
{
static private ReaderWriterLockSlim rwl = new ReaderWriterLockSlim();//读写锁
static void Main(string[] args)
{
//如果某个线程进入了写入模式,那么其他线程无论是要写入还是读取,都是会被阻塞的
Task t_write1 = new Task(WriteSomething);
t_write1.Start();
Console.WriteLine("{0} Create Thread ID {1} , Start WriteSomething", DateTime.Now.ToString("hh:mm:ss fff"), t_write1.GetHashCode());
Task t_write2 = new Task(WriteSomething);
t_write2.Start();
Console.WriteLine("{0} Create Thread ID {1} , Start WriteSomething", DateTime.Now.ToString("hh:mm:ss fff"), t_write2.GetHashCode());
//当某个线程进入读取模式时,此时其他线程依然能进入读取模式,假设此时一个线程要进入写入模式,那么他不得不被阻塞。直到读取模式退出为止。
Task t_read1 = new Task(ReadSomething);
t_read1.Start();
Console.WriteLine("{0} Create Thread ID {1} , Start ReadSomething", DateTime.Now.ToString("hh:mm:ss fff"), t_read1.GetHashCode());
Task t_read2 = new Task(ReadSomething);
t_read2.Start();
Console.WriteLine("{0} Create Thread ID {1} , Start ReadSomething", DateTime.Now.ToString("hh:mm:ss fff"), t_read2.GetHashCode());
Console.ReadKey();
}
static public void ReadSomething()
{
Console.WriteLine("*************************************读取模式*********************************************");
Console.WriteLine("{0} Thread ID {1} Begin EnterReadLock...", DateTime.Now.ToString("hh:mm:ss fff"), Task.CurrentId.GetHashCode());
rwl.EnterReadLock();//进入读取模式锁定状态
try
{
Console.WriteLine("{0} Thread ID {1} reading sth...", DateTime.Now.ToString("hh:mm:ss fff"), Task.CurrentId.GetHashCode());
Thread.Sleep(5000);//模拟读取信息
Console.WriteLine("{0} Thread ID {1} reading end.", DateTime.Now.ToString("hh:mm:ss fff"), Task.CurrentId.GetHashCode());
}
finally
{
rwl.ExitReadLock();
Console.WriteLine("{0} Thread ID {1} ExitReadLock...", DateTime.Now.ToString("hh:mm:ss fff"), Task.CurrentId.GetHashCode());
}
}
static public void WriteSomething()
{
Console.WriteLine("***********************************写入模式***************************************************");
Console.WriteLine("{0} Thread ID {1} Begin EnterWriteLock...", DateTime.Now.ToString("hh:mm:ss fff"), Task.CurrentId.GetHashCode());
rwl.EnterWriteLock();//进入写入模式锁定状态
try
{
Console.WriteLine("{0} Thread ID {1} writing sth...", DateTime.Now.ToString("hh:mm:ss fff"), Task.CurrentId.GetHashCode());
Thread.Sleep(10000);//模拟写入信息
Console.WriteLine("{0} Thread ID {1} writing end.", DateTime.Now.ToString("hh:mm:ss fff"), Task.CurrentId.GetHashCode());
}
finally
{
rwl.ExitWriteLock();
Console.WriteLine("{0} Thread ID {1} ExitWriteLock...", DateTime.Now.ToString("hh:mm:ss fff"), Task.CurrentId.GetHashCode());
}
}
}
}

输出结果如下:

02:29:04 442 Create Thread ID 59835590 , Start WriteSomething
02:29:04 458 Create Thread ID 66433212 , Start WriteSomething
02:29:04 458 Create Thread ID 42109742 , Start ReadSomething
02:29:04 458 Create Thread ID 14556615 , Start ReadSomething
***********************************写入模式***************************************************
02:29:04 459 Thread ID 2 Begin EnterWriteLock...
02:29:04 459 Thread ID 2 writing sth...
*************************************读取模式*********************************************
02:29:04 462 Thread ID 3 Begin EnterReadLock...
*************************************读取模式*********************************************
02:29:04 465 Thread ID 4 Begin EnterReadLock...
***********************************写入模式***************************************************
02:29:04 469 Thread ID 1 Begin EnterWriteLock...
02:29:14 462 Thread ID 2 writing end.
02:29:14 462 Thread ID 2 ExitWriteLock...
02:29:14 462 Thread ID 1 writing sth...
02:29:24 463 Thread ID 1 writing end.
02:29:24 463 Thread ID 1 ExitWriteLock...
02:29:24 463 Thread ID 4 reading sth...
02:29:24 463 Thread ID 3 reading sth...
02:29:29 464 Thread ID 4 reading end.
02:29:29 464 Thread ID 4 ExitReadLock...
02:29:29 464 Thread ID 3 reading end.
02:29:29 464 Thread ID 3 ExitReadLock...

发现2号写线程结束后(经过10s),1号写线程才进入写任务,1号线程执行10s后,3号和4号同时执行读任务。

C#读写锁ReaderWriteLockSlim的使用的更多相关文章

  1. 技术笔记:Delphi多线程应用读写锁

    在多线程应用中锁是一个很简单又很复杂的技术,之所以要用到锁是因为在多进程/线程环境下,一段代码可能会被同时访问到,如果这段代码涉及到了共享资源(数据)就需要保证数据的正确性.也就是所谓的线程安全.之前 ...

  2. java多线程-读写锁

    Java5 在 java.util.concurrent 包中已经包含了读写锁.尽管如此,我们还是应该了解其实现背后的原理. 读/写锁的 Java 实现(Read / Write Lock Java ...

  3. 让C#轻松实现读写锁分离

    ReaderWriterLockSlim 类 表示用于管理资源访问的锁定状态,可实现多线程读取或进行独占式写入访问. 使用 ReaderWriterLockSlim 来保护由多个线程读取但每次只采用一 ...

  4. C#读写锁ReaderWriterLockSlim的使用

    读写锁的概念很简单,允许多个线程同时获取读锁,但同一时间只允许一个线程获得写锁,因此也称作共享-独占锁.在C#中,推荐使用ReaderWriterLockSlim类来完成读写锁的功能. 某些场合下,对 ...

  5. 可重入锁 公平锁 读写锁、CLH队列、CLH队列锁、自旋锁、排队自旋锁、MCS锁、CLH锁

    1.可重入锁 如果锁具备可重入性,则称作为可重入锁. ========================================== (转)可重入和不可重入 2011-10-04 21:38 这 ...

  6. 用读写锁三句代码解决多线程并发写入文件 z

    C#使用读写锁三句代码简单解决多线程并发写入文件时提示“文件正在由另一进程使用,因此该进程无法访问此文件”的问题 在开发程序的过程中,难免少不了写入错误日志这个关键功能.实现这个功能,可以选择使用第三 ...

  7. 锁的封装 读写锁、lock

    最近由于项目上面建议使用读写锁,而去除常见的lock锁.然后就按照需求封装了下锁.以简化锁的使用.但是开发C#的童鞋都知道lock关键字用起太方便了,但是lock关键字不支持超时处理.很无奈,为了实现 ...

  8. Java多线程13:读写锁和两种同步方式的对比

    读写锁ReentrantReadWriteLock概述 大型网站中很重要的一块内容就是数据的读写,ReentrantLock虽然具有完全互斥排他的效果(即同一时间只有一个线程正在执行lock后面的任务 ...

  9. 让C#轻松实现读写锁分离--封装ReaderWriterLockSlim

    ReaderWriterLockSlim 类 表示用于管理资源访问的锁定状态,可实现多线程读取或进行独占式写入访问. 使用 ReaderWriterLockSlim 来保护由多个线程读取但每次只采用一 ...

随机推荐

  1. 域名+端口号 访问minio服务问题

    业务上需要用到分布式文件服务,选择了minio作为文件服务的组件,搭建好服务后使用IP+端口号(http://xx.xx.xx.xx:9001)的形式访问在所有环境下都没有问题. 上线部署时出于正规和 ...

  2. wsl创建证书让chrome浏览器识别

    我在wsl里面测试http2协议的时候,在wsl用openssl创建了证书, 然后我把证书放在windows证书管理后,用chrome打开发现提示这个: 虽然可以点击下面的强制 访问 但是chrome ...

  3. Homework5

    问:什么是分而治之? 答:分而治之就是通过一系列的方法,将复杂的问题逐渐划分成若干份相对简单的问题的方法,对每个相对简单问题进行一一解决,若干个简单问题的解的集合就是一个复杂问题的解.分而治之的应用体 ...

  4. 使用spfa算法判断有没有负环

    如果存在最短路径的边数大于等于点数,就有负环 给定一个n个点m条边的有向图,图中可能存在重边和自环, 边权可能为负数. 请你判断图中是否存在负权回路. 输入格式 第一行包含整数n和m. 接下来m行每行 ...

  5. Mysql阶段性项目——QQ数据库管理

    MySql 数据库设计与应用 第七章项目练习 阶段项目--QQ数据库管理 任务概述: 模拟QQ在线聊天系统 后台数据库的创建 基本数据表的创建 表约束. 表间关系的添加 进行数据增加. 删除. 修改. ...

  6. 通过vNode实现给列表字段打标签

    问题 如何给列表数据打标签?类似下面这种样子 思路 数模转化(对接口请求回来的数据进行过滤标记,返回新的数据) 渲染新的数据模型 实现 1.过滤数据,需要打标签的采用jsx写法 业务数据的处理我封装在 ...

  7. 前端必读3.0:如何在 Angular 中使用SpreadJS实现导入和导出 Excel 文件

    在之前的文章中,我们为大家分别详细介绍了在JavaScript.React中使用SpreadJS导入和导出Excel文件的方法,作为带给广大前端开发者的"三部曲",本文我们将为大家 ...

  8. URL Search查询

    #基本查询 GET /movies/_search?q=2012&df=title&sort=year:desc&from=0&size=10&timeout= ...

  9. MySQL手动恢复数据库测试操作

    事件背景 MySQL数据库每日零点自动全备 某天上午9点,二狗子不小心drop了一个数据库 我们需要通过全备的数据文件,以及增量的binlog文件进行数据恢复 主要思想与原理 利用全备的sql文件中记 ...

  10. 驱动开发:内核CR3切换读写内存

    首先CR3是什么,CR3是一个寄存器,该寄存器内保存有页目录表物理地址(PDBR地址),其实CR3内部存放的就是页目录表的内存基地址,运用CR3切换可实现对特定进程内存地址的强制读写操作,此类读写属于 ...