使用Mutex类-互斥锁

owned为true,互斥锁的初始状态就是被主线程所获取,否则处于未获取状态

name为定义的互斥锁名称,在整个操作系统只有一个命名未CSharpThreadingCookbook的互斥量,一个线程得到,其他线程就无法得到这个互斥量了,只能等待。

const string mutexName = "CSharpThreadingCookbook";
public Mutex(bool initiallyOwned, string mutexName);
public Mutex();

WaitOne():获取,mut.ReleaseMutex():释放

public override bool WaitOne()
public static Mutex mutex = new Mutex();

//获取互斥锁,已经被其他线程获取,挂起等待。
mut.WaitOne();
//代码
//...
//... //释放锁
mut.ReleaseMutex();

SemaphoreSlim类,限制同一资源被同时访问的线程数量

有10个线程同时去访问数据库,借助信号类限制访问数据的并发线程数量,当有4个线程同时正在访问资源,其他线程必须等待,直至有资源执行完被释放。

class Program
{
static SemaphoreSlim _seamp = new SemaphoreSlim(4);
static void Main(string[] args)
{
for (int i = ; i <=; i++)
{
int j = i;
int sencondsToWait = + * i;
var t = new Thread(()=> { method(j.ToString(),sencondsToWait); });
t.Start();
}
Console.ReadLine();
}
static void method(string name,int senconds)
{
Console.WriteLine($"{name} waits to access a database");
_seamp.Wait();
Console.WriteLine($"{name} is completed");
Thread.Sleep(TimeSpan.FromSeconds(senconds));
_seamp.Release();
}
}

ManualResetEvent:线程间相互通信,一个线程开始一个活动,结束后告诉另一个线程可以进行执行了。

通过构造函数来控制 ManualResetEvent 的初始状态。

1.当初始值未false时,为非终止状态;_mre.WaitOne()阻塞线程,不允许线程访问下边的语句

static ManualResetEvent _mre = new ManualResetEvent(false);

2.当初始值未true时,为终止状态;_mre.WaitOne()允许线程访问下边的语句

static ManualResetEvent _mre = new ManualResetEvent(true);

在非终止状态时怎么让线程继续执行,怎么再让它停下来,这就要用了set()和Reset()方法了

  • 把非终止状态改为终止状态用Set()方法,告诉线程活动可以继续执行了(打开大门)
  • 把终止状态改为非终止状态用Reset()方法,阻塞线程直到再调用 Set()方法(关闭大门直至打开)

场景:

一个线程进行一个活动后,调用WaitOne()阻塞线程,等待其他线程给我信号我再继续执行。

另一个线程执行Set(),告诉正在等我执行完的线程,你可以执行了。随后Reset(),没有来得及执行的线程只能继续等待,直至再次接收信号。

CountDownEvent:信号类,等待直到一定数量的操作完成。

创建一个CountDownEvent实例,在构造函数中指定了当两个操作完成时会发出信号

static CountDownEvent _countDown = new CountDownEvent();
static void method()
{
Console.WriteLine("");
_countDown.Signal();
} var t1=new thread(()=>method());
t1.Start();
_countDown.Wait();
_countDown.dispose();
如果_countDown.Signal()没有达到指定的次数,那么_countDown.Wait()会一直等待,所以上面代码将会一值等待。

Barrier:像一个屏障,把所有线程任务的阶段隔离开来,当前阶段所有线程不完成,不会开始下一个阶段。

当屏障接收到所有的参与者,participantCount: 参与线程的数量,完成某个阶段的信号后,就会执行“阶段后代码”,

然后barrier.CurrentPhaseNumber会递增其值,表示要运行新的阶段,然后再解除阻塞每一个参与者的Task实例,然后所有参与者开始下一个阶段。

让【多个任务】在【不同阶段】同步一次(碰面),在继续往后执行。

        //同步两个线程,以及指定回调函数
static Barrier _barrier = new Barrier(, b => Console.WriteLine($"{b.CurrentPhaseNumber+1}当前阶段线程都执行完了,碰面一次") );
static void Main(string[] args)
{ var t1 = new Thread(() => Method_1());
var t2 = new Thread(() => Method_2());
t1.Start();
t2.Start();
Console.ReadLine();
} /// <summary>
/// 线程1要执行的方法
/// </summary>
public static void Method_1()
{
//模拟阶段一
Thread.Sleep(TimeSpan.FromSeconds());
Console.WriteLine("【阶段一】,线程【1】执行完毕");
_barrier.SignalAndWait(); //模拟阶段二
Thread.Sleep(TimeSpan.FromSeconds());
Console.WriteLine("【阶段二】,线程【1】执行完毕");
_barrier.SignalAndWait();
} /// <summary>
/// 线程2要执行的方法
/// </summary>
public static void Method_2()
{
//模拟阶段一
Thread.Sleep(TimeSpan.FromSeconds());
Console.WriteLine("【阶段一】,线程【2】执行完毕");
_barrier.SignalAndWait(); //模拟阶段二
Thread.Sleep(TimeSpan.FromSeconds());
Console.WriteLine("【阶段二】,线程【2】执行完毕");
_barrier.SignalAndWait(); }

运行结果:

【C#多线程编程实战笔记】二、 线程同步的更多相关文章

  1. C#多线程编程实战(二)

    1.1 简介 为了防止一个应用程序控制CPU而导致其他应用程序和操作系统本身永远被挂起这一可能情况,操作系统不得不使用某种方式将物理计算分割为一些虚拟的进程,并给予每个执行程序一定量的计算能力.此外操 ...

  2. C#多线程编程实战(二):线程同步

    2.1 简介 竞争条件:多个线程同时使用共享对象.需要同步这些线程使得共享对象的操作能够以正确的顺序执行 线程同步问题:多线程的执行并没有正确的同步,当一个线程执行递增和递减操作时,其他线程需要依次等 ...

  3. 【C#多线程编程实战笔记】一、 线程基础

    创建线程 Thread :所执行的方法不能有参数. class Program { static void Main(string[] args) { Console.WriteLine(" ...

  4. C#多线程编程实战1.6线程优先级

    using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...

  5. Java多线程编程实战指南(核心篇)读书笔记(二)

    (尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/76651408冷血之心的博客) 博主准备恶补一番Java高并发编程相 ...

  6. Python GUI之tkinter窗口视窗教程大集合(看这篇就够了) JAVA日志的前世今生 .NET MVC采用SignalR更新在线用户数 C#多线程编程系列(五)- 使用任务并行库 C#多线程编程系列(三)- 线程同步 C#多线程编程系列(二)- 线程基础 C#多线程编程系列(一)- 简介

    Python GUI之tkinter窗口视窗教程大集合(看这篇就够了) 一.前言 由于本篇文章较长,所以下面给出内容目录方便跳转阅读,当然也可以用博客页面最右侧的文章目录导航栏进行跳转查阅. 一.前言 ...

  7. Java多线程编程实战指南(核心篇)读书笔记(五)

    (尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/76730459冷血之心的博客) 博主准备恶补一番Java高并发编程相 ...

  8. Java多线程编程实战指南(核心篇)读书笔记(三)

    (尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/76686044冷血之心的博客) 博主准备恶补一番Java高并发编程相 ...

  9. 《Java多线程编程实战指南(核心篇)》阅读笔记

    <Java多线程编程实战指南(核心篇)>阅读笔记 */--> <Java多线程编程实战指南(核心篇)>阅读笔记 Table of Contents 1. 线程概念 1.1 ...

随机推荐

  1. nodeJS之URL

    前面的话 在HTTP部分,详细介绍了URL的相关知识.而nodejs中的url模块提供了一些实用函数,用于URL处理与解析.本文将详细介绍nodeJS中的URL URL对象 解析 URL 对象有以下内 ...

  2. 深入浅出数据结构C语言版(12)——从二分查找到二叉树

    在很多有关数据结构和算法的书籍或文章中,作者往往是介绍完了什么是树后就直入主题的谈什么是二叉树balabala的.但我今天决定不按这个套路来.我个人觉得,一个东西或者说一种技术存在总该有一定的道理,不 ...

  3. HAproxy部署配置

    HAproxy部署配置 拓扑图 说明: haproxy服务器IP:172.16.253.200/16 (外网).192.168.29.140/24(内网) 博客服务器组IP:192.168.29.13 ...

  4. swift 导出测试包(Save for Ad Hoc Deployment)卡在compile bitcode处问题

    如图取消Rebuild from bitcode选中速度会快很多

  5. 应届毕业生如何通过学习Linux系统选择一份高薪职业

    2017年全国高校毕业生人数795万,史上"更难就业季"大学生就业形势,再加上出国留学回来的约30万以及没有找到工作的往届毕业生,预计将有1000多万大学生同时竞争. 如果我们不是 ...

  6. 【CPP】概览

    [使用C语言的七个步骤]1:定义程序目标  2:设计程序  3:编写代码  4:编译  5:运行  6:测试和调试  7:维护和修改 [程序细节] :#include 指示和头文件 include&l ...

  7. DoNet 高效开发必备开发工具

    工欲善其事,必先利其器,没有好的工具,怎么能高效的开发出高质量的代码呢? 本文为 ASP.NET 开发者介绍一些高效实用的工具,包括 SQL 管理,VS插件,内存管理,诊断工具等,涉及开发过程的各个环 ...

  8. Vue过渡效果之CSS过渡

    前面的话 Vue 在插入.更新或者移除 DOM 时,提供多种不同方式的应用过渡效果.本文将从CSS过渡transition.CSS动画animation及配合使用第三方CSS动画库(如animate. ...

  9. 错误 0xc0202049: 数据流任务 1: 无法在只读列“ID”中插入数据

    数据库导入导出时总失败,错误信息如下: 正在验证 (错误) 消息错误 0xc0202049: 数据流任务 1: 无法在只读列“ID”中插入数据. (SQL Server 导入和导出向导) 错误 0xc ...

  10. tomcat websocket 实现网页在线即时聊天

    背景介绍 近一个月完成了公司的一个项目,负责即时聊天部分 寻找了一下,决定使用websocket,要问原因的话,因为tomcat 自带相关消息收发的API,用起来方便 闲话少叙,进入实现步骤 使用工具 ...