ObjectPool 对象池设计模式

2023-10-19 19:36:46 浏览数 (1)

Micosoft.Extension.ObjectPool

源码架构、模式分析:

三大基本对象:

  1. ObjectPool抽象类
  2. ObjectPoolProvider抽象类
  3. IPooledObjectPolicy接口

ObjectPool的默认实现是DefaultPool,对象池的创建由ObjectPoolProvider抽象类的默认实现DefaultObjectPoolProvider类实现。

代码语言:javascript复制
public class DefaultObjectPoolProvider : ObjectPoolProvider
{
    /// <summary>
    /// The maximum number of objects to retain in the pool.
    /// </summary>
    public int MaximumRetained { get; set; } = Environment.ProcessorCount * 2;

    /// <inheritdoc/>
    public override ObjectPool<T> Create<T>(IPooledObjectPolicy<T> policy)
    {
        if (policy == null)
        {
            throw new ArgumentNullException(nameof(policy));
        }

        if (typeof(IDisposable).IsAssignableFrom(typeof(T)))
        {
            return new DisposableObjectPool<T>(policy, MaximumRetained);
        }

        return new DefaultObjectPool<T>(policy, MaximumRetained);
    }
}

IPooledObjectPolicy接口有对应的抽象类及默认实现,对象池中的对象(也就是池对象)的创建或返回由此策略类来控制。

代码语言:javascript复制
public override T Get()
{
    var item = _firstItem;
    if (item == null || Interlocked.CompareExchange(ref _firstItem, null, item) != item)
    {
        var items = _items;
        for (var i = 0; i < items.Length; i  )
        {
            item = items[i].Element;
            if (item != null && Interlocked.CompareExchange(ref items[i].Element, null, item) == item)
            {
                return item;
            }
        }

        item = Create();
    }

    return item;
}

// Non-inline to improve its code quality as uncommon path
[MethodImpl(MethodImplOptions.NoInlining)]
private T Create() => _fastPolicy?.Create() ?? _policy.Create();

public override void Return(T obj)
{
    if (_isDefaultPolicy || (_fastPolicy?.Return(obj) ?? _policy.Return(obj)))
    {
        if (_firstItem != null || Interlocked.CompareExchange(ref _firstItem, obj, null) != null)
        {
            var items = _items;
            for (var i = 0; i < items.Length && Interlocked.CompareExchange(ref items[i].Element, obj, null) != null;   i)
            {
            }
        }
    }
}

从整体的设计思路来说,提供者Provider用来提供具体的对象池,传入的参数也是策略类,而策略类则把控池对象的具体处理。dotnet core中很多源码的开发模式都是这种:通过Policy构建Provider,通过Provider创建最终的类。也就是说,只通过策略类来实现自定义扩展,这种架构可以借鉴和思考。

0 人点赞