zoukankan      html  css  js  c++  java
  • [转]ObjectPool

    ObjectPool
    //#define DISABLE_POOL
    using System;
    using System.Collections.Generic;
    using System.Text;

    namespace ObjectPool {
    public interface IObjectPoolMethods : IDisposable {
    /// <summary>
    /// This method is used to setup an instance of
    /// an object.
    /// </summary>
    /// <remarks>
    /// Use an empty constructor in the class and
    /// entirely rely on this method to setup and
    /// initialize the object if the class is going
    /// to be used for object pooling. Do not call this
    /// method from the constructor or it will be called
    /// twice and will affect performace.
    /// </remarks>
    /// <param name="setupParameters"></param>
    void SetupObject(params object[] setupParameters);
    /// <summary>
    /// This event must be fired when dispose is called
    /// or the Object Pool will not be able to work
    /// </summary>
    event EventHandler Disposing;
    }

    /// <summary>
    /// A generic class that provide object pooling functionality
    /// to classes that implement the IObjectPoolMethods interface
    /// </summary>
    /// <remarks>
    /// As long as the lock(this) statements remain this class is thread
    /// </remarks>
    /// <typeparam name="T">
    /// The type of the object that should be pooled
    /// </typeparam>
    public class ObjectPool<T> where T : IObjectPoolMethods, new() {
    /// <summary>
    /// The MAX_POOL does not restrict the maximum
    /// number of objects in the object pool
    /// instead it restricts the number of
    /// disposed objects that the pool will maintain
    /// a reference too and attempt to pool. This
    /// number should be set based on a memory and
    /// usage anaylsis based on the types of objects
    /// being pooled. I have found the best results
    /// by setting this number to average peak objects
    /// in use at one time.
    /// </summary>
    /// <value>100</value>
    private const int MAX_POOL = 2000;
    /// <summary>
    /// The static instance of the object pool. Thankfully the
    /// use of generics eliminates the need for a hash for each
    /// different pool type
    /// </summary>
    private static ObjectPool<T> me = new ObjectPool<T>();
    /// <summary>
    /// Using a member for the max pool count allows different
    /// types to have a different value based on usage analysis
    /// </summary>
    private int mMaxPool = ObjectPool<T>.MAX_POOL;
    /// <summary>
    /// A Linked List of the WeakReferences to the objects in the pool
    /// When the count of the list goes beyond the max pool count
    /// items are removed from the end of the list. The objects at the
    /// end of the list are also most likely to have already been collected
    /// by the garbage collector.
    /// </summary>
    private LinkedList<WeakReference> objectPool = new LinkedList<WeakReference>();
    /// <summary>
    /// Return the singleton instance
    /// </summary>
    /// <returns>
    /// The single instance allowed for the given type
    /// </returns>
    public static ObjectPool<T> GetInstance() {
    return me;
    }
    /// <summary>
    /// This method gets called on the object disposing
    /// event for objects created from this object pool class.
    /// If the implementing class does not fire this event on
    /// dispose the object pooling will not work
    /// </summary>
    /// <param name="sender">
    /// The class instance that is pooled
    /// </param>
    /// <param name="e">
    /// An empty event args parameters
    /// </param>
    /// <exception cref="System.ArgumentException">
    /// Thrown if the type of the object in the weak reference does not match
    /// the type of this generic instance
    /// </exception>
    private void Object_Disposing(object sender, EventArgs e) {
    //The lock is required here because this method may
    //be called from events on different threads
    lock (this) {
    Add(
    new WeakReference(sender));
    }
    }
    /// <summary>
    /// This method will add a new instance to be tracked by
    /// this object pooling class. This should be a reference
    /// to an object that was just disposed otherwise it makes no
    /// sense and will likely cause some serious problems.
    /// </summary>
    /// <param name="weak">
    /// WeakReference to the object that was disposed
    /// </param>
    /// <exception cref="System.ArgumentException">
    /// Thrown if the type of the object in the weak reference does not match
    /// the type of this generic instance
    /// </exception>
    private void Add(WeakReference weak) {
    objectPool.AddFirst(weak);
    if (objectPool.Count >= mMaxPool) {
    objectPool.RemoveLast();
    }
    }
    /// <summary>
    /// Remove the reference from the pool. This should
    /// only be called when the object in the pool
    /// is being reactivated or if the weak reference has
    /// been determined to be expired.
    /// </summary>
    /// <param name="weak">
    /// A reference to remove
    /// </param>
    /// <exception cref="System.ArgumentException">
    /// Thrown if the type of the object in the weak reference does not match
    /// the type of this generic instance
    /// </exception>
    private void Remove(WeakReference weak) {
    objectPool.Remove(weak);
    }
    ///<summary>
    /// This method will verify that the type of the weak
    /// reference is valid for this generic instance. I haven't
    /// figured out a way do it automagically yet
    /// </summary>
    /// <exception cref="System.ArgumentException">
    /// Thrown if the type of the object in the weak reference does not match
    /// the type of this generic instance
    /// </exception>
    private void TypeCheck(WeakReference weak) {
    if (weak.Target != null && weak.Target.GetType() != typeof(T)) {
    throw new ArgumentException("Target type does not match pool type", "weak");
    }
    }

    /// <summary>
    /// This method will return an object reference that is fully
    /// setup. It will either retrieve the object from the object
    /// pool if there is a disposed object available or it will
    /// create a new instance.
    /// </summary>
    /// <param name="setupParameters">
    /// The setup parameters required for the
    /// IObjectPoolMethods.SetupObject method. Need to find a
    /// way to check for all of the types efficiently and at
    /// compile time.
    /// </param>
    /// <returns>
    /// The reference to the object
    /// </returns>
    public T GetObjectFromPool(params object[] setupParameters) {
    T result
    = default(T);
    #if DISABLE_POOL
    result
    = new T();
    result.SetupObject(setupParameters);
    return result;
    #else
    lock (this) {
    WeakReference remove
    = null;
    foreach (WeakReference weak in objectPool) {
    object o = weak.Target;
    if (o != null) {
    remove
    = weak;
    result
    = (T)o;
    GC.ReRegisterForFinalize(result);
    break;
    }
    }
    if (remove != null) {
    objectPool.Remove(remove);
    }
    }
    if (result == null) {
    result
    = new T();
    result.Disposing
    += new EventHandler(Object_Disposing);
    }
    result.SetupObject(setupParameters);
    return result;
    #endif
    }


    }
    }
    SampleObject
  • 相关阅读:
    7、NFC技术:让Android自动运行程序
    6、Android中的NFC技术
    5、NFC概述
    Delphi XE7中开发安卓程序一些有用的帮助资源
    Delphi开发安卓程序的感受
    Tomcat绿色版启动"startup.bat"一闪问题的解决方法!
    Delphi判断字符串中是否包含汉字,并返回汉字位置
    Delphi的DLL里如何实现定时器功能?
    Delphi的DLL里如何实现定时器功能?
    VS2013如何添加LIb库及头文件的步骤
  • 原文地址:https://www.cnblogs.com/Googler/p/1754572.html
Copyright © 2011-2022 走看看