对象池

作者: Sczlog | 来源:发表于2019-02-12 14:33 被阅读1次
    using System;
    using System.Collections.Concurrent;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    
    namespace ConsoleApplication6
    {
        class Program
        {
            static void 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, 500, (i, loopState) =>
                {
                    MyClass mc = pool.GetObject();
                    mc.GetValue(i);
                    Thread.Sleep(500);
                    // 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();
            }
        }
    
        public class ObjectPool<T>
        {
            private ConcurrentQueue<T> _objects;
            private Func<T> _objectGenerator;
            private static int COUNT = 0;
            private int _size;
    
            public ObjectPool(Func<T> objectGenerator,int size = 5)
            {
                if (objectGenerator == null) throw new ArgumentNullException("objectGenerator");
                this._size = size;
                _objects = new ConcurrentQueue<T>();
                _objectGenerator = objectGenerator;
            }
    
            public T GetObject()
            {
                T item = default(T);
                if (_objects.TryDequeue(out item)){
                    Console.WriteLine("Here is a available resource");
                    return item;
                }else
                {
                    if (COUNT <= _size)
                    {
                        Console.WriteLine("Here is more capacity, create a new resource");
                        COUNT++;
                        return _objectGenerator();
                    }
                    return GetObjectAsync().Result;
                }
            }
    
            private async Task<T> GetObjectAsync() {
                await Task.Run(() =>
                {
                    int i = 0;
                    while (_objects.Count == 0) {
                        i++;
                        Task.Delay(100);
                    }
                    Console.WriteLine("Pool is fullified, cannot insert new object, wait for release after " +i+" times tries");
                    return;
                });
                Console.WriteLine("Here is a released resource");
                return GetObject();
            }
    
    
            public void PutObject(T item)
            {
                T temp;
                if (_objects.Count > 5)
                {
                    _objects.TryDequeue(out temp);
                }
                _objects.Enqueue(item);
            }
        }
    
        class MyClass
        {
            public int[] Nums { get; set; }
            public double GetValue(long i)
            {
                return Math.Sqrt(Nums[i]);
            }
            public MyClass()
            {
                Nums = new int[1000000];
                Random rand = new Random();
                for (int i = 0; i < Nums.Length; i++)
                    Nums[i] = rand.Next();
            }
        }
    
    }
    
    

    相关文章

      网友评论

          本文标题:对象池

          本文链接:https://www.haomeiwen.com/subject/seckeqtx.html