c#线程同步使用详解示例


在C#中,线程同步是确保多个线程在访问共享资源时不会相互干扰的关键机制。这里,我将提供一个简单的示例,展示如何使用`lock`关键字来实现线程同步。`lock`是C#中用于同步访问代码块的简单机制,它基于`Monitor`类实现。

### 示例:使用`lock`进行线程同步

假设我们有一个简单的计数器类,多个线程将尝试同时增加这个计数器的值。为了确保计数的准确性,我们需要使用线程同步。


using System;
using System.Threading;

public class Counter
{
    // 定义一个对象作为锁
    private readonly object _lockObject = new object();
    // 计数器变量
    private int _count = 0;

    // 增加计数的方法
    public void Increment()
    {
        // 使用lock关键字锁定_lockObject对象
        lock (_lockObject)
        {
            // 临界区:只有获得锁的线程才能执行这里的代码
            _count++;
            // 临界区结束
        }
        // 锁在离开lock块时自动释放
    }

    // 获取当前计数的值
    public int Count => _count;
}

class Program
{
    static void Main(string[] args)
    {
        Counter counter = new Counter();

        // 创建并启动多个线程来增加计数器的值
        for (int i = 0; i < 10; i++)
        {
            Thread thread = new Thread(() =>
            {
                for (int j = 0; j < 1000; j++)
                {
                    counter.Increment();
                }
            });
            thread.Start();
        }

        // 等待所有线程完成
        Thread.Sleep(2000); // 假设所有线程在2秒内完成

        // 输出最终的计数
        Console.WriteLine($"Final Count: {counter.Count}");
    }
}

在这个示例中,`Counter`类有一个`Increment`方法,该方法使用`lock`关键字来确保在增加`_count`变量时,没有其他线程可以执行这个操作。`_lockObject`是一个私有对象,用作锁定的目标。任何尝试进入`lock`块的线程都必须先获得`_lockObject`的锁。如果锁已被其他线程占用,则尝试进入`lock`块的线程将被阻塞,直到锁被释放。

请注意,虽然`lock`是线程同步的一种简单有效方式,但在使用时也需要注意避免死锁和性能问题。此外,C#还提供了其他同步机制,如`Monitor`类、`Mutex`、`Semaphore`、`Interlocked`类以及`async`和`await`模式等,这些都可以根据具体场景选择使用。