zoukankan      html  css  js  c++  java
  • C# 对象池的实现

    C# 对象池的实现

    对象池服务可以减少从头创建每个对象的系统开销。在激活对象时,它从池中提取。在停用对象时,它放回池中,等待下一个请求。
    我们来看下主线程中,如何与对象池打交道:

    复制代码
    static void Main(string[] args)
            {
                InstancePoolResolver.Register<OrderQueryServiceInterface, OrderQueryService>();
    
                while (true)
                {
                    Thread.Sleep(2000);
                    Console.Clear();
    
                    for (int i = 0; i < 20;i++ )
                    {
                        ThreadPool.QueueUserWorkItem(new WaitCallback(ConsumeObject));
                    }
                }
            }
    
            private static void ConsumeObject(object state)
            {
                OrderQueryServiceInterface srv = null;
                try
                {
                    using (srv = InstancePoolResolver.Resolve<OrderQueryServiceInterface>())  //从对象池中取得对象,没有可用对象则throw exception
                    {
                        Console.WriteLine("Object ID--->" + srv.GetHashCode());
                        Thread.Sleep(1000);  //故意长时间占用对象
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
                finally
                {
                    if (srv != null)
                        srv.Dispose();
                }
            }
    复制代码

     运行效果:

    最多只有2个instance,那在哪里设置这个数量呢?请看

    是通过Attribute打tag上去的

    下面来看看最核心的InstancePoolResolver类

    复制代码
    public sealed class InstancePoolResolver
        {
            private static Dictionary<Type, Type> typeMappers = new Dictionary<Type, Type>();
            private static Dictionary<Type, int> typeMappersMaxInstanceCount = new Dictionary<Type, int>();
            private static Dictionary<Type, List<PoolableObject>> typeInstances = new Dictionary<Type, List<PoolableObject>>();
    
            private static object o4lock = new object();
            public static void Register<T, TProvider>()
                where TProvider : class, new()
            {
                if (typeMappers.ContainsKey(typeof(T)))
                    throw new Exception("Key existed");
                
                lock (o4lock)
                {
                    Type t = typeof(T);
                    typeMappers.Add(t, typeof(TProvider));
                    typeInstances.Add(t, new List<PoolableObject>());
    
                    InstanceSettingAttribute setting = GetInstanceSettingAttribute(typeof(TProvider));
                    typeMappersMaxInstanceCount.Add(t, setting.MaxInstanceGlobal);
                }
            }
    
            public static T Resolve<T>()
                where T: PoolableObject
            {
                Type t = typeof(T);
                if (!typeMappers.ContainsKey(t) || !typeInstances.ContainsKey(t))
                    throw new Exception("Key empty, register please");
    
                lock (o4lock)
                {
                    List<PoolableObject> instances = typeInstances[t];
                    if (instances == null)
                    {
                        instances = new List<PoolableObject>();
                        typeInstances[t] = instances;
                    }
                    foreach (PoolableObject o in instances)//是否已经存在已有闲置对象
                    {
                        if (o.IsInPool)
                        {
                            o.IsInPool = false;
                            return (T)o;
                        }
                    }
                    if (instances.Count < typeMappersMaxInstanceCount[t])//new新对象到对象池中
                    {
                        Type type = typeMappers[t];
                        PoolableObject obj = (PoolableObject)Activator.CreateInstance(type);
                        instances.Add(obj);
                        obj.IsInPool = false;
                        return (T)obj;
                    }
                }
                throw new Exception("Object Pool fulled!"); //没有多余的资源
            }
    
            private static InstanceSettingAttribute GetInstanceSettingAttribute(Type type)
            {
                object[] attrs = type.GetCustomAttributes(typeof(InstanceSettingAttribute), false);
                if (attrs == null || attrs.Count() == 0)
                    return new InstanceSettingAttribute() {  MaxInstanceGlobal=10};
    
                return (InstanceSettingAttribute)attrs[0];
            }
        }
    复制代码

    其实很简单,只是多了个获取Attribute的函数

    自省推动进步,视野决定未来。
    心怀远大理想。
    为了家庭幸福而努力。
    用A2D科技,服务社会。
     
    分类: 架构可扩展
  • 相关阅读:
    jemeter使用笔记
    webtest mobile + Android / Battery Historian / SoloPi
    script / go / golang
    my live house / air conditioning / dajin / dakin / FTXG50JV2CW
    OS + Centos OS 8 Thinkpad TrackPoint
    network router Gpon
    Mybatisplus 自定义sql 使用条件构造器 多表查询分页
    处理fastJson 序列化时间问题
    js 实现轮播图 超级简单 组件已封装
    Webpack-dev-server的proxy用法
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3224147.html
Copyright © 2011-2022 走看看