zoukankan      html  css  js  c++  java
  • C# LIFOPool 对象池

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

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

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

    #region Fields
    private WeakEvent<EventHandler> eventFull;
    private LookupItem<T> lookupItem;
    private ReleaseItem<T> releaseItem;
    private double 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
    <WeakEvent<EventHandler>>(ref eventFull, new WeakEvent<EventHandler>(), null);
    }
    eventFull.Add(value);
    }
    remove
    {
    if (eventFull != null)
    {
    eventFull.Remove(value);
    }
    }
    }
    public double LifeTime
    {
    set { Interlocked.Exchange(ref lifeTime, value); }
    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 LIFOPool(LookupItem<T> createDelegate, ReleaseItem<T> releaseDelegate)
    :
    this(DefaultMinSize, DefaultMaxSize, createDelegate, releaseDelegate)
    {

    }
    public LIFOPool(int min, int max, LookupItem<T> lookupDelegate, ReleaseItem<T> releaseDelegate)
    {
    if (lookupDelegate ="color: #000000;">== null)
    {
    throw new ArgumentNullException("Lookup delegate can't be null.");
    }
    T t1
    = lookupDelegate(), t2 = lookupDelegate();
    if (object.ReferenceEquals(t1, t2))
    {
    throw new ArgumentException("Lookup delegate can't return the same reference object.");
    }
    lookupItem
    = lookupDelegate;
    releaseItem
    = releaseDelegate;
    lifeTime
    = Freer.DefaultLifeTime / 2D;
    minSize
    = min;
    maxSize
    = max;
    freeTimeout
    = 2000;
    weakHandle
    = new GCHandle[maxSize / 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].LastUpdate = container[1].LastUpdate = DateTime.Now;
    container[
    0].Value = t1;
    container[
    1].Value = t2;
    offset
    ++;
    locker
    = new ReaderWriterLockSlim();
    }
    #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].LastUpdate
    = DateTime.Now;
    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)
    {
    weakHandle[i].Target
    = null;
    item
    = (T)weakHandle[i].Target;
    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;
    container[i].LastUpdate
    = DateTime.Now;
    }
    finally
    {
    locker.ExitWriteLock();
    }
    item
    = container[i].Value;
    break;
    }
    }
    if (item == null)
    {
    locker.EnterWriteLock();
    try
    {
    container[offset].Idle
    = false;
    container[offset].LastUpdate
    = DateTime.Now;
    item
    = container[offset++].Value = lookupItem();
    }
    finally
    {
    locker.ExitWriteLock();
    }
    }
    }
    finally
    {
    locker.ExitUpgradeableReadLock();
    }
    }
    return item;
    }

    public int Free()
    {
    int freed = 0;
    if (lifeTime != Timeout.Infinite && offset > minSize - 1)
    {
    List
    <T> list = null;
    if (locker.TryEnterWriteLock(freeTimeout))
    {
    try
    {
    LIFOEntry entry;
    for (int i = 0; i <= offset; i++)
    {
    entry
    = container[i];
    if (entry.LastUpdate.AddSeconds(lifeTime).CompareTo(DateTime.Now) <= 0)
    {
    if (IsSubOfIDisposable && entry.Idle)
    {
    if (list == null)
    {
    list
    = new List<T>();
    }
    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;
    }
    }
    }
    }
    finally
    {
    locker.ExitWriteLock();
    }
    }
    if (list != null)
    {
    list.ForEach(item
    => ((IDisposable)item).Dispose());
    }
    }
    return freed;
    }
    #endregion
    }
  • 相关阅读:
    【Java EE 学习 36】【struts2】【struts2系统验证】【struts2 ognl值栈】【struts2 ongl标签】【struts2 UI标签】【struts2模型驱动和令牌机制】
    【Java EE 学习 35 下】【struts2】【struts2文件上传】【struts2自定义拦截器】【struts2手动验证】
    【Java EE 学习 35 上】【strus2】【类型转换器】【struts2和Servlet API解耦】【国际化问题】【资源文件乱码问题已经解决】
    【Java EE 学习 34】【struts2学习第一天】
    【JavaScript中的正则表达式】
    【Java EE 学习 33 下】【validate表单验证插件】
    【Java EE 学习 33 上】【JQuery样式操作】【JQuery中的Ajax操作】【JQuery中的XML操作】
    【Java EE 学习 32 下】【JQuery】【JQuey中的DOM操作】
    【Java EE 学习 32 上】【JQuery】【选择器】
    【Java EE 学习 31】【JavaScript基础增强】【Ajax基础】【Json基础】
  • 原文地址:https://www.cnblogs.com/Googler/p/1752314.html
Copyright © 2011-2022 走看看