C# 语言中的并发设计模式

作者:微信公众号:【架构师老卢】
8-24 18:54
12

概述:本文介绍了具有双重检查锁定的单例、具有有界缓冲区的生产者-消费者模式以及线程本地存储模式。Singleton with Double-Check Locking(双校验锁定单例)Singleton 模式确保一个类只有一个实例,并提供对该实例的全局访问点。Double-checked locking 是一种通过在获取锁之前检查实例是否存在来提高性能的技术。private static Singleton instance; private static readonly object lockObject = new object(); public static Singleton G

本文介绍了具有双重检查锁定的单例、具有有界缓冲区的生产者-消费者模式以及线程本地存储模式。

Singleton with Double-Check Locking(双校验锁定单例)

Singleton 模式确保一个类只有一个实例,并提供对该实例的全局访问点。

Double-checked locking 是一种通过在获取锁之前检查实例是否存在来提高性能的技术。

private static Singleton instance;  
private static readonly object lockObject = new object();  
  
public static Singleton GetInstance()  
{  
    if (instance == null)  
    {  
        lock (lockObject)  
        {  
            if (instance == null)  
            {  
                instance = new Singleton();  
            }  
        }  
    }  
    return instance;  
}

具有有界缓冲区的生产者-消费者模式

生产者-消费者模式涉及两个部分:创建数据并将其放入共享资源(缓冲区)的生产者,以及从共享资源获取数据并处理数据的消费者。

有界缓冲区限制缓冲区可以容纳的项目数,防止生产者过度生产和消费者使用不存在的项目。

private Queue<T> buffer = new Queue<T>(); // Shared buffer to hold items  
private int maxSize; // Maximum size of the buffer  
  
public void Produce(T item)  
{  
    // Acquire a lock on the buffer to ensure mutual exclusion  
    lock (buffer)  
    {  
        // While the buffer is full, wait until a consumer consumes an   
        //item and signals  
        while (buffer.Count >= maxSize)  
        {  
            //Releases the lock acquired by lock (buffer) and waits for a   
            //signal (Pulse or PulseAll) to reacquire the lock and continue   
            //execution.  
            Monitor.Wait(buffer);  
        }  
  
        buffer.Enqueue(item);  
          
        //Notifies all waiting consumers. Signal that there's an   
        //item available for consumption  
        Monitor.PulseAll(buffer);  
    }  
}  
  
public T Consume()  
{  
    // Acquire a lock on the buffer to ensure mutual exclusion  
    lock (buffer)  
    {  
        // While the buffer is empty, wait until a producer   
        //produces an item and signals  
        while (buffer.Count == 0)  
        {  
            // Release the lock and wait for PulseAll signal  
            Monitor.Wait(buffer);  
        }  
  
        T item = buffer.Dequeue();  
  
        // Signal that there's space available for producing more items  
        Monitor.PulseAll(buffer);  
  
        return item;  
    }  
}  

线程本地存储模式

线程本地存储 (TLS) 模式允许每个线程唯一地访问数据。当多个线程需要不应在线程之间共享的独立数据实例时,此模式非常有用。

public class ThreadLocalData  
{  
    private static ThreadLocal<int> threadLocalData = new ThreadLocal<int>(() =>  
    {  
        return Thread.CurrentThread.ManagedThreadId;  
    });  
  
    public static int GetThreadLocalData()  
    {  
        return threadLocalData.Value;  
    }  
}

使用案例:

  • 具有双重检查锁定的单例: 当需要以最少的开销对单一实例进行延迟初始化时使用。
  • 具有有界缓冲区的生产者-消费者模式: 在协调多个线程之间的数据交换,同时限制共享缓冲区的大小时使用。
  • 线程本地存储模式: 当每个线程都需要自己的数据实例(不应与其他线程共享)时使用。
阅读排行