当前位置:首页 > 技术知识 > 正文内容

C# 中的多线程同步机制:lock、Monitor 和 Mutex 用法详解

maynowei3周前 (08-03)技术知识17

在多线程编程中,线程同步是确保多个线程安全地访问共享资源的关键技术。C# 提供了几种常用的同步机制,其中 lock、Monitor 和 Mutex 是最常用的同步工具。本文将全面介绍这三种同步机制的用法、优缺点以及适用场景,帮助开发者在多线程开发中做出合适的选择。

1. lock 关键字 1.1 概述 在 C# 中,lock 关键字是用于线程同步的最常用工具之一。lock 是 Monitor.Enter() 和 Monitor.Exit() 的语法糖,通过锁住一个共享资源来确保在同一时刻只有一个线程可以访问它。lock 适用于同一个进程中的线程同步,尤其是在多个线程访问共享数据时,能够有效地防止数据竞态和线程安全问题。

1.2 用法 lock 关键字的常见用法是围绕一个对象的引用,将其作为锁对象来同步线程。通常,lock 语句会包装一个临界区(共享资源访问区),当一个线程执行完临界区代码后,另一个线程才能进入临界区。 示例代码:

using System;

using System.Threading;

class Program

{

private static readonly object _lock = new object();

// 锁对象

static void Main()

{

Thread t1 = new Thread(DoWork);

Thread t2 = new Thread(DoWork);

t1.Start();

t2.Start();

}

static void DoWork()

{ lock (_lock) // 获取锁 { Console.WriteLine("线程进入临界区...");

Thread.Sleep(1000);

// 模拟处理时间 Console.WriteLine("线程离开临界区...");

}

}

}

说明: 在 lock (_lock) 中,_lock 是锁对象。lock 保证了在同一时刻只有一个线程可以进入 lock 语句块内部的代码。 lock 会在代码块执行完毕后自动释放锁,无需手动释放。 1.3 优缺点 优点: 语法简洁,易于理解和使用。 自动释放锁,减少了因为忘记释放锁而导致死锁的风险。 缺点: 只能用于同一个进程中的线程之间的同步,不能跨进程使用。 无法提供更多的同步控制,比如等待和通知机制。

2. Monitor 类 2.1 概述 Monitor 类是 C# 提供的底层同步机制,比 lock 更加灵活和精细。Monitor 提供了对锁的手动控制,允许你在获取锁后,等待其他线程的通知或条件满足才能继续执行。Monitor 适合那些需要更多同步控制的场景,比如等待和通知机制。 2.2 用法 Monitor 类提供了几个关键的方法: Enter(object obj):尝试获取锁,如果成功,线程继续执行。 Exit(object obj):释放锁,允许其他线程访问锁定的资源。 Wait(object obj):使当前线程等待,直到其他线程通知它。 Pulse(object obj):唤醒一个等待该锁的线程。 PulseAll(object obj):唤醒所有等待该锁的线程。 示例代码:

using System;

using System.Threading;

class Program

{

private static readonly object _lock = new object(); // 锁对象

static void Main()

{

Thread t1 = new Thread(DoWork);

Thread t2 = new Thread(DoWork);

t1.Start();

t2.Start();

}

static void DoWork()

{

Monitor.Enter(_lock);// 获取锁 try

{ Console.WriteLine("线程进入临界区...");

Thread.Sleep(1000);

// 模拟工作

Console.WriteLine("线程离开临界区...");

}

finally { Monitor.Exit(_lock);

// 确保释放锁 } } }

说明:

Monitor.Enter(_lock) 获取锁,Monitor.Exit(_lock) 释放锁。 Monitor 更加底层,提供了细粒度的控制,适用于复杂的同步场景。 使用 try/finally 语句确保即使在发生异常时,也能释放锁。 2.3 优缺点 优点: 比 lock 更灵活,支持等待和通知机制,如 Wait、Pulse 和 PulseAll。 适用于需要更多控制的同步场景。 缺点: 使用起来相对复杂,容易出错,尤其是在手动管理锁时。 只支持同一进程内的线程同步。

相关文章

Axure RP设计伸缩导航、遮罩弹窗、返回顶部的方法

以下几小教程使用的是Axure的动态面板来实现,内容简单,适合菜鸟查阅,老鸟可飘过,顺便帮忙点个赞哈/偷笑。一.伸缩/隐藏导航栏例如:鼠标移动到一级导航上,二级导航会下拉方式显示1.打开Axure,拖...

在手机上演示axure原型(怎么在axure中画出手机原型)

AXSHARE APP发布啦,以后大家的原型可以通过这款APP进行预览演示咯。小编迫不及待的体验了一下这款APP。要使用这款APP,首先需要有axshare的账号。账号注册地址:https://sha...

记录程序第一天挖漏洞的过程(挖漏洞需要学什么语言)

第一个漏洞复现fastjson漏洞说明:在本地这个fastjson会出现问题复现的过程生成一个java文件进行攻击注入的方式javac Exploit.java但是必须编译成.class文件才能执行p...

那些技术—Listview的性能提高篇(listview提高效率)

ListView优化一直是一个老生常谈的问题,不管是面试还是平常的开发中,ListView永远不会被忽略掉,那么这篇文章我们来看看如何最大化的优化ListView的性能。 · 1.在adapter中的...

有了这份900多页的Android面试指南,你离大厂Offer还远吗?

前言对于大部分程序员来说,一线互联网是的工作经历是毕生的追求,实际上大厂对于学历的要求远远没有我们想象的那么高,近几年来,互联网公司更注重技术,所以提升自身技术水平才是斩获offer的制胜关键。一线互...

Android指示器,轮播与循环轮播(android轮播图代码)

Android UI Libs之CircleIndicator1. 说明CircleIndicator,顾名思义,圆形指示器,只一个可以用来做轮播的第三方库。2. 配置在模块的build.gradle...