MST

星途 面试题库

面试题:C#中多线程同步的常见方式

请列举C#中用于多线程同步的至少三种常见方式,并简要说明它们的适用场景和工作原理。
18.1万 热度难度
编程语言C#

知识考点

AI 面试

面试题答案

一键面试
  1. Mutex(互斥锁)

    • 适用场景:适用于跨进程的线程同步,确保同一时间只有一个线程或进程能够访问共享资源。例如,在多个进程可能同时访问一个系统资源(如文件、串口等)时使用。
    • 工作原理:Mutex有一个名为“拥有者”的概念。当一个线程获取Mutex时,它成为拥有者,其他线程若想获取则必须等待,直到拥有者释放Mutex。在.NET中,Mutex类提供了WaitOne方法用于获取Mutex,ReleaseMutex方法用于释放Mutex。
  2. Semaphore(信号量)

    • 适用场景:适用于控制同时访问共享资源的线程数量。比如,一个数据库连接池有固定数量的连接,信号量可以控制同时使用连接的线程数量,避免过多线程竞争导致连接耗尽。
    • 工作原理:Semaphore维护一个计数,初始时设置为允许同时访问的最大线程数。每次线程调用WaitOne获取信号量时,计数减1;当计数为0时,其他线程获取信号量会被阻塞。线程调用Release方法释放信号量,计数加1。
  3. Monitor(监视器)

    • 适用场景:常用于同一进程内的线程同步,在保护一段代码(临界区)不被多个线程同时执行时非常有效。例如,多个线程可能同时访问和修改一个共享的集合,使用Monitor可以确保在同一时间只有一个线程能操作该集合。
    • 工作原理:Monitor基于对象锁定机制。每个对象都有一个隐藏的同步块,线程通过Monitor.Enter方法尝试获取对象的锁(进入同步块),若获取成功则可以执行临界区代码,执行完后通过Monitor.Exit方法释放锁。如果锁已被其他线程持有,Monitor.Enter会阻塞调用线程直到锁可用。C#中的lock关键字本质上就是对Monitor.EnterMonitor.Exit的封装。
  4. AutoResetEvent(自动重置事件)

    • 适用场景:用于线程间的简单通知,当一个线程完成某个操作后通知另一个线程开始工作。比如,一个数据处理线程完成数据准备后通知计算线程开始计算。
    • 工作原理:它有两种状态:终止状态和非终止状态。初始化为非终止状态时,调用WaitOne方法的线程会被阻塞。当调用Set方法时,事件变为终止状态,等待的一个线程会被释放,然后事件自动重置为非终止状态,其他等待线程仍会被阻塞。
  5. ManualResetEvent(手动重置事件)

    • 适用场景:与AutoResetEvent类似,但适用于需要一次性通知多个线程的场景。例如,初始化完成后,通知所有等待的线程开始工作。
    • 工作原理:同样有终止和非终止两种状态。调用Set方法将其设置为终止状态,所有调用WaitOne等待的线程都会被释放,直到调用Reset方法将其设置回非终止状态,否则等待线程不会被阻塞。