zoukankan      html  css  js  c++  java
  • 自己写的ObjectPool类谨供参考学习。。。

    #region Delegate
    public delegate T LookupItem<T>();
    public delegate void ReleaseItem<T>(T item);
    #endregion

    #region ObjectPool
    public class ObjectPool<T> : IPool<T>, IFreeness where T : class
    {
    #region NestedTypes
    internal struct LIFOEntry
    {
    public bool Idle;
    public DateTime CreateTime;
    public T Value;
    }
    #endregion

    #region StaticMembers
    public const int DefaultMinSize = 2;
    public const int DefaultMaxSize = 100;
    internal static readonly bool IsSubOfIDisposable;

    static ObjectPool()
    {
    IsSubOfIDisposable
    = typeof(T).IsSubclassOf(typeof(IDisposable));
    }
    #endregion

    #region Fields
    private WeakEvent<EventHandler> eventFull;
    private LookupItem<T> lookupItem;
    private ReleaseItem<T> releaseItem;
    private TimeSpan lifeTime;
    private int minSize, maxSize, offset, freeTimeout;
    private GCHandle[] weakHandle;
    private LIFOEntry[] container;
    private ReaderWriterLockSlim locker;
    #endregion

    #region Properties
    public event EventHandler Full
    {
    add
    {
    if (eventFull == null)
    {
    Interlocked.CompareExchange(
    ref eventFull, new WeakEvent<EventHandler>(), null);
    }
    eventFull.Add(value);
    }
    remove
    {
    if (eventFull != null)
    {
    eventFull.Remove(value);
    }
    }
    }
    public TimeSpan LifeTime
    {
    get { return lifeTime; }
    }
    int IFreeness.Capacity
    {
    get { return maxSize; }
    }
    public int MinSize
    {
    get { return minSize; }
    }
    public int MaxSize
    {
    get { return maxSize; }
    }
    public int Size
    {
    get { return offset + 1; }
    }
    public bool IsFull
    {
    get { return offset + 1 == maxSize; }
    }
    public int FreeTimeout
    {
    set { Interlocked.Exchange(ref freeTimeout, value); }
    get { return freeTimeout; }
    }
    #endregion

    #region Constructor
    public ObjectPool(LookupItem<T> createDelegate, ReleaseItem<T> releaseDelegate, TimeSpan timeout)
    :
    this(createDelegate, releaseDelegate, Freer.LifeTime, DefaultMinSize, DefaultMaxSize)
    {

    }
    public ObjectPool(LookupItem<T> lookupDelegate, ReleaseItem<T> releaseDelegate, TimeSpan timeout, int min, int max)
    {
    AppDiag.GuardArgument(lookupDelegate,
    "lookupDelegate");
    T t1
    = lookupDelegate(), t2 = lookupDelegate();
    AppDiag.GuardArgument(
    object.ReferenceEquals(t1, t2), "Lookup delegate can't return the same reference object.");
    lookupItem
    = lookupDelegate;
    releaseItem
    = releaseDelegate;
    lifeTime
    = timeout;
    AppDiag.GuardArgument(min
    < 0, "The min size must > -1.");
    AppDiag.GuardArgument(max
    < 2, "The max size must > 1.");
    minSize
    = min;
    maxSize
    = max;
    freeTimeout
    = 2000;
    weakHandle
    = new GCHandle[max / 10];
    GCHandle emptyHandle
    = GCHandle.Alloc(null, GCHandleType.Weak);
    for (int i = 0; i < weakHandle.Length; i++)
    {
    weakHandle[i]
    = emptyHandle;
    }
    container
    = new LIFOEntry[maxSize];
    container[
    0].Idle = container[1].Idle = true;
    container[
    0].CreateTime = container[1].CreateTime = DateTime.UtcNow;
    container[
    0].Value = t1;
    container[
    1].Value = t2;
    offset
    ++;
    locker
    = new ReaderWriterLockSlim();
    Freer.Instance.Add(
    this);
    }
    #endregion

    #region Methods
    public void Store(T item)
    {
    if (releaseItem != null)
    {
    releaseItem(item);
    }
    locker.EnterUpgradeableReadLock();
    try
    {
    int index = -1;
    for (int i = offset; i > 0; i--)
    {
    if (container[i].Value.Equals(item))
    {
    locker.EnterWriteLock();
    try
    {
    container[i].Idle
    = true;
    }
    finally
    {
    locker.ExitWriteLock();
    }
    index
    = i;
    break;
    }
    }
    if (index == -1)
    {
    locker.EnterWriteLock();
    try
    {
    if (offset + 1 == maxSize && (eventFull == null || !eventFull.Raise(this, EventArgs.Empty)))
    {
    throw new PoolFullException();
    }
    container[offset].Idle
    = true;
    container[offset].CreateTime
    = DateTime.UtcNow;
    container[offset
    ++].Value = item;
    }
    finally
    {
    locker.ExitWriteLock();
    }
    }
    }
    finally
    {
    locker.ExitUpgradeableReadLock();
    }
    }

    public T Retrieve()
    {
    T item
    = null;
    locker.EnterReadLock();
    try
    {
    for (int i = 0; i < weakHandle.Length; i++)
    {
    if (weakHandle[i].Target != null)
    {
    item
    = (T)weakHandle[i].Target;
    weakHandle[i].Target
    = null;
    break;
    }
    }
    }
    finally
    {
    locker.ExitReadLock();
    }
    if (item == null)
    {
    locker.EnterUpgradeableReadLock();
    try
    {
    if (offset + 1 == maxSize && (eventFull == null || !eventFull.Raise(this, EventArgs.Empty)))
    {
    throw new PoolFullException();
    }
    for (int i = offset; i > 0; i--)
    {
    if (container[i].Idle)
    {
    locker.EnterWriteLock();
    try
    {
    container[i].Idle
    = false;
    }
    finally
    {
    locker.ExitWriteLock();
    }
    item
    = container[i].Value;
    break;
    }
    }
    if (item == null)
    {
    locker.EnterWriteLock();
    try
    {
    container[offset].Idle
    = false;
    container[offset].CreateTime
    = DateTime.UtcNow;
    item
    = container[offset++].Value = lookupItem();
    }
    finally
    {
    locker.ExitWriteLock();
    }
    }
    }
    finally
    {
    locker.ExitUpgradeableReadLock();
    }
    }
    return item;
    }

    public int Free()
    {
    int freed = 0;
    if (lifeTime != TimeSpan.Zero && offset > minSize - 1)
    {
    if (locker.TryEnterWriteLock(freeTimeout))
    {
    try
    {
    LIFOEntry entry;
    if (IsSubOfIDisposable)
    {
    List
    <T> list = new List<T>();
    for (int i = 0; i <= offset; i++)
    {
    entry
    = container[i];
    if (DateTime.UtcNow - entry.CreateTime >= lifeTime)
    {
    if (entry.Idle)
    {
    list.Add(container[i].Value);
    }
    int j = i;
    while (j < offset)
    {
    entry
    = container[j];
    int nextJ = ++j;
    container[j]
    = container[nextJ];
    container[nextJ]
    = entry;
    }
    for (j = 0; j < weakHandle.Length; j++)
    {
    if (weakHandle[i].Target == null)
    {
    weakHandle[i].Target
    = container[offset].Value;
    container[offset].Value
    = null;
    break;
    }
    }
    freed
    ++;
    if (offset-- <= minSize)
    {
    break;
    }
    }
    }
    list.ForEach(item
    => ((IDisposable)item).Dispose());
    }
    else
    {
    for (int i = 0; i <= offset; i++)
    {
    entry
    = container[i];
    if (DateTime.UtcNow - entry.CreateTime >= lifeTime)
    {
    int j = i;
    while (j < offset)
    {
    entry
    = container[j];
    int nextJ = ++j;
    container[j]
    = container[nextJ];
    container[nextJ]
    = entry;
    }
    for (j = 0; j < weakHandle.Length; j++)
    {
    if (weakHandle[i].Target == null)
    {
    weakHandle[i].Target
    = container[offset].Value;
    container[offset].Value
    = null;
    break;
    }
    }
    freed
    ++;
    if (offset-- <= minSize)
    {
    break;
    }
    }
    }
    }
    }
    finally
    {
    locker.ExitWriteLock();
    }
    }
    }
    return freed;
    }
    #endregion
    }
    #endregion

    #region PoolFullException
    public class PoolFullException : Exception
    {
    public PoolFullException()
    :
    base("Object Pool is Full.")
    {

    }
    public PoolFullException(string msg)
    :
    base(msg)
    {

    }
    }
    #endregion
  • 相关阅读:
    Hive分组取Top N
    Hive 锁 lock
    Hive创建指向HBase表的表
    Hive Serde
    自定义UDF
    Hive使用SequenceFile存储数据
    alter table
    describe命令
    移动端,字体实际大小比设置的大,原因总结
    移动端适配基础总结
  • 原文地址:https://www.cnblogs.com/Googler/p/1981442.html
Copyright © 2011-2022 走看看