线程同步(笔记)
时间:2020-04-28
本文章向大家介绍线程同步(笔记),主要包括线程同步(笔记)使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
两种情况:用户模式和内核模式
一 用户模式
相当于运行自己写的程序,在里面设置线程同步
有volatile和interlocked两者方式
1 volatile
static bool _stop; public static void Run() {//主线程 Task.Run(() => {//任务线程 int number = 1; while (!Volatile.Read(ref _stop)) //读取_stop { number++; } Console.WriteLine($"increase stopped,value = {number}"); }); Thread.Sleep(1000); _stop = true; //更新_stop }
2 interlocked
private static void DoIncrease(int incrementPerThread) { int number1 = 0; int number2 = 0; Console.WriteLine($"use two threads to increase zero. each thread increase {incrementPerThread}."); IList<Task> increaseTasks = new List<Task>(); increaseTasks.Add(Task.Run(() => { Console.WriteLine($"thread #{Thread.CurrentThread.ManagedThreadId} increasing number1."); for (int i = 0; i < incrementPerThread; i++) { Interlocked.Increment(ref number1); } })); increaseTasks.Add(Task.Run(() => { Console.WriteLine($"thread #{Thread.CurrentThread.ManagedThreadId} increasing number1."); for (int i = 0; i < incrementPerThread; i++) { Interlocked.Increment(ref number1); } })); increaseTasks.Add(Task.Run(() => { Console.WriteLine($"thread #{Thread.CurrentThread.ManagedThreadId} increasing number2."); for (int i = 0; i < incrementPerThread; i++) { number2++; } })); increaseTasks.Add(Task.Run(() => { Console.WriteLine($"thread #{Thread.CurrentThread.ManagedThreadId} increasing number2."); for (int i = 0; i < incrementPerThread; i++) { number2++; } })); Task.WaitAll(increaseTasks.ToArray()); Console.WriteLine($"use interlocked: number1 result = {number1}"); Console.WriteLine($"normal increase: number2 result = {number2}"); }
二 内核模式
有事件、信号量和互斥量这三种方式
1 事件 AutoResetEvent
private static void DoIncrease(int incrementPerThread) { int number = 0; Console.WriteLine($"use two threads to increase zero. each thread increase {incrementPerThread}."); AutoResetEvent are = new AutoResetEvent(true);//初始化一个终止状态的线程同步事件 IList<Task> increaseTasks = new List<Task>(); increaseTasks.Add(Task.Run(() => { Console.WriteLine($"thread #{Thread.CurrentThread.ManagedThreadId} is increasing the number."); for (int i = 0; i < incrementPerThread; i++) { are.WaitOne();// 阻塞线程,直到被同步事件唤醒 number++; are.Set();// 将事件设为终止状态,唤醒其他线程 } })); increaseTasks.Add(Task.Run(() => { Console.WriteLine($"thread #{Thread.CurrentThread.ManagedThreadId} is increasing the number."); for (int i = 0; i < incrementPerThread; i++) { are.WaitOne(); number++; are.Set(); } })); Task.WaitAll(increaseTasks.ToArray()); are.Dispose(); Console.WriteLine($"use AutoResetEvent: result = {number}"); }
2 信号量 Semaphore
private static void DoIncrease(int incrementPerThread) { int number = 0; Console.WriteLine($"use two threads to increase zero. each thread increase {incrementPerThread}."); Semaphore semaphore = new Semaphore(1,1); //初始化信号量,这里初始值要设置为1,否则同步会有问题 IList<Task> increaseTasks = new List<Task>(); increaseTasks.Add(Task.Run(() => { Console.WriteLine($"thread #{Thread.CurrentThread.ManagedThreadId} is increasing the number."); for (int i = 0; i < incrementPerThread; i++) { semaphore.WaitOne(); number++; semaphore.Release(1);// 退出信号量 } })); increaseTasks.Add(Task.Run(() => { Console.WriteLine($"thread #{Thread.CurrentThread.ManagedThreadId} is increasing the number."); for (int i = 0; i < incrementPerThread; i++) { semaphore.WaitOne(); number++; semaphore.Release(1); } })); Task.WaitAll(increaseTasks.ToArray()); semaphore.Dispose(); Console.WriteLine($"use Semaphore: result = {number}"); }
3 互斥量 Mutex
bool createNew; using (new Mutex(true, Assembly.GetExecutingAssembly().FullName, out createNew)) { if (!createNew) {//系统已经存在同名的互斥体,说明已有程序实例在运行 //这里做一些提示 Environment.Exit(0);//退出 } else { //启动实例的代码 } }
三 混合模式
1 Lock
2 ReaderWriterLockSlim
private static readonly ReaderWriterLockSlim _rwlock = new ReaderWriterLockSlim(); public static void DoWork() { _rwlock.EnterWriteLock(); //DoWork _rwlock.ExitWriteLock(); }
原文地址:https://www.cnblogs.com/wwz-wwz/p/12794781.html
- 图片和视频防盗链简单介绍
- 对比cp和scp命令 将数据从一台linux服务器复制到另一台linux服务器
- laravel—用Migration的操作数据库
- 有货移动Web端性能优化探索实践
- webpack打包速度和性能再次优化
- MySQL 清除表空间碎片
- 解决ios不支持按钮:active伪类的方法
- HTTP-FLV直播初探
- BZOJ1058: [ZJOI2007]报表统计
- React数据流和组件间的通信总结
- react+redux+webpack教程4
- 洛谷P2391 白雪皑皑(并查集)
- BZOJ4514: [Sdoi2016]数字配对(费用流)
- 3.2数据结构之指针和链表 1748:约瑟夫问题
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Spring 基于设值函数的依赖注入
- Spring 基于构造函数的依赖注入
- 绕过卡巴进程保护的一些总结
- Loki | 数据过期自动删除策略设计
- 【短道速滑二】古老的基于亮度平均值的自动Gamma校正算法。
- Docker-Compose基础与实战,看这一篇就够了
- 干货-python与安全(一)入门简介
- 怎么在vue的style标签里面使用变量?
- 幼儿园EasyNVR能力层安防监控平台调用视频直播流报404错误解决方案
- C# WinForm捕获全局异常
- 新时代渗透思路!微服务下的信息收集Ⅱ
- 【STM32F407开发板用户手册】第31章 STM32F407的SPI总线基础知识和HAL库API
- 【工具使用】红队工具之Faction
- 【WebGL】一次drawcall中绘制多个不同纹理的图形
- BERT的PyTorch实现