海量编程文章、技术教程与实战案例

网站首页 > 技术文章 正文

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

yimeika 2025-05-15 22:55:18 技术文章 5 ℃

在多线程编程中,线程同步是确保多个线程安全地访问共享资源的关键技术。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。 适用于需要更多控制的同步场景。 缺点: 使用起来相对复杂,容易出错,尤其是在手动管理锁时。 只支持同一进程内的线程同步。

Tags:

最近发表
标签列表