菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
295
0

object pool

原创
05/13 14:22
阅读数 7327
/// <summary>
    /// 对象池
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class ObjectPool<T>
    {
        private readonly ConcurrentBag<T> _buffer;

        private readonly Func<T> _createFunc;
        private readonly Action<T> _resetFunc;

        public int Capacity { get; private set; }

        private readonly int _chunkSize;
        public int Count { get { return _buffer.Count; } }

        public ObjectPool(Func<T> createFunc, Action<T> resetFunc, int capacity = 50, int chunkSize = 10)
        {
            if (createFunc == null)
            {
                throw new ArgumentNullException("createFunc");
            }
            if (capacity <= 0)
            {
                throw new ArgumentOutOfRangeException("capacity");
            }
            if (chunkSize <= 0)
            {
                throw new ArgumentOutOfRangeException("chunkSize");
            }

            this._buffer = new ConcurrentBag<T>();
            this._createFunc = createFunc;
            this._resetFunc = resetFunc;

            this.Capacity = capacity;
            this._chunkSize = chunkSize;

            AllocateChunk();
        }

        public T GetObject()
        {
            T obj;
            if (!_buffer.TryTake(out obj))
            {
                //创建一些数据
                AllocateChunk();
                _buffer.TryTake(out obj);  
            }
            return obj;
        }

        public void ReleaseObject(T obj)
        {
            Contract.Assume(obj != null);

            //超过容量了,不再需要
            if (Count >= Capacity) return;

            if (_resetFunc != null)
            {
                _resetFunc(obj);
            }

            _buffer.Add(obj);
        }

        private void AllocateChunk()
        {
            for (int i = 0; i < _chunkSize; i++)
            {
                _buffer.Add(_createFunc());
            }
        }
    }
class Program
    {
       staticvoid Main(string[] args)
        {
            CancellationTokenSource cts = new CancellationTokenSource();

            // Create an opportunity for the user to cancel.
            Task.Run(() =>
                {
                    if (Console.ReadKey().KeyChar == 'c' || Console.ReadKey().KeyChar == 'C')
                        cts.Cancel();
                });

            ObjectPool<MyClass> pool = new ObjectPool<MyClass> (() => new MyClass());            

            // Create a high demand for MyClass objects.
            Parallel.For(0, 1000000, (i, loopState) =>
                {
                    MyClass mc = pool.GetObject();
                    Console.CursorLeft = 0;
                    // This is the bottleneck in our application. All threads in this loop// must serialize their access to the static Console class.
                    Console.WriteLine("{0:####.####}", mc.GetValue(i));                 

                    pool.PutObject(mc);
                    if (cts.Token.IsCancellationRequested)
                        loopState.Stop();                 

                });
            Console.WriteLine("Press the Enter key to exit.");
            Console.ReadLine();
            cts.Dispose();
        }
    }

 

发表评论

0/200
295 点赞
0 评论
收藏