C# ThreadContextPool 对象池

public class ThreadContextPool<T> where T : class
{
#region NestedType
private struct Entry
{
public int ThreadID;
public T Value;
}

private struct PendingEntry
{
public int ThreadID;
public int ReturnCount;
}

private class GlobalPool
{
private int maxCount;
private Stack<T> items;

public int MaxCount
{
get { return maxCount; }
set
{
lock (items)
{
while (items.Count > value)
{
items.Pop();
}
maxCount
= value;
}
}
}

public GlobalPool(int maxCount)
{
this.maxCount = maxCount;
this.items = new Stack<T>();
}

public void Clear()
{
lock (items)
{
items.Clear();
}
}

public void DecrementMaxCount()
{
lock (items)
{
if (items.Count == maxCount)
{
items.Pop();
}
maxCount
--;
}
}

public bool Return(T value)
{
if (items.Count < MaxCount)
{
lock (items)
{
if (items.Count < MaxCount)
{
items.Push(value);
return true;
}
}
}
return false;
}

public T Take()
{
if (items.Count > 0)
{
lock (items)
{
if (items.Count > 0)
{
return items.Pop();
}
}
}
return null;
}
}
#endregion

#region Fields
private const int maxPendingEntries = 128;
private const int maxPromotionFailures = 64;
private const int maxReturnsBeforePromotion = 64;
private const int maxThreadItemsPerProcessor = 16;
private int maxCount, promotionFailures;
private Entry[] entries;
private PendingEntry[] pending;
private GlobalPool globalPool;
#endregion

#region Properties
public int MinSize
{
get { return 0; }
}
public int MaxSize
{
get { return maxCount; }
}
public int Size
{
get { throw new NotSupportedException(); }
}
#endregion

#region Methods
public ThreadContextPool(int maxCount)
{
int num = maxCount;
int num2 = maxThreadItemsPerProcessor + Environment.ProcessorCount;
if (num > num2)
{
num
= num2;
}
this.maxCount = maxCount;
this.entries = new Entry[num];
this.pending = new PendingEntry[4];
this.globalPool = new GlobalPool(maxCount);
}

public void Clear()
{
for (int i = 0; i < entries.Length; i++)
{
entries[i].Value
= null;
}
globalPool.Clear();
}

public bool Return(T item)
{
int managedThreadId = Thread.CurrentThread.ManagedThreadId;
if (managedThreadId == 0)
{
return false;
}
bool flag = ReturnToPerThreadPool(managedThreadId, item);
if (!flag)
{
RecordReturnToGlobalPool(managedThreadId);
flag
= globalPool.Return(item);
}
return flag;
}

private bool ReturnToPerThreadPool(int thisThreadID, T value)
{
for (int i = 0; i < entries.Length; i++)
{
int threadID = entries[i].ThreadID;
if (threadID == thisThreadID)
{
if (entries[i].Value == null)
{
entries[i].Value
= value;
return true;
}
return false;
}
if (threadID == 0)
{
break;
}
}
return false;
}

private void RecordReturnToGlobalPool(int thisThreadID)
{
for (int i = 0; i < pending.Length; i++)
{
int threadID = pending[i].ThreadID;
if (threadID == thisThreadID)
{
int num3 = pending[i].ReturnCount + 1;
if (num3 < maxReturnsBeforePromotion)
{
pending[i].ReturnCount
= num3;
return;
}
pending[i].ReturnCount
= 0;
if (!PromoteThread(thisThreadID))
{
HandlePromotionFailure(thisThreadID);
return;
}
break;
}
if (threadID == 0)
{
return;
}
}
}
private bool PromoteThread(int thisThreadID)
{
lock (entries)
{
for (int i = 0; i < entries.Length; i++)
{
int threadID = entries[i].ThreadID;
if (threadID == thisThreadID)
{
return true;
}
if (threadID == 0)
{
globalPool.DecrementMaxCount();
entries[i].ThreadID
= thisThreadID;
return true;
}
}
}
return false;
}
private void HandlePromotionFailure(int thisThreadID)
{
int num = promotionFailures + 1;
if (num >= maxPromotionFailures)
{
lock (entries)
{
entries
= new Entry[entries.Length];
globalPool.MaxCount
= maxCount;
}
PromoteThread(thisThreadID);
}
else
{
promotionFailures
= num;
}
}

public T Take()
{
int managedThreadId = Thread.CurrentThread.ManagedThreadId;
if (managedThreadId == 0)
{
return null;
}
T local
= this.TakeFromPerThreadPool(managedThreadId);
if (local != null)
{
return local;
}
this.RecordTakeFromGlobalPool(managedThreadId);
return globalPool.Take();
}

private T TakeFromPerThreadPool(int thisThreadID)
{
for (int i = 0; i < entries.Length; i++)
{
int threadID = entries[i].ThreadID;
if (threadID == thisThreadID)
{
T local
= entries[i].Value;
if (local != null)
{
entries[i].Value
= null;
return local;
}
return null;
}
if (threadID == 0)
{
break;
}
}
return null;
}

private void RecordTakeFromGlobalPool(int thisThreadID)
{
for (int i = 0; i < pending.Length; i++)
{
int threadID = pending[i].ThreadID;
if (threadID == thisThreadID)
{
return;
}
if (threadID == 0)
{
lock (pending)
{
if (pending[i].ThreadID == 0)
{
pending[i].ThreadID
= thisThreadID;
return;
}
}
}
}
if (pending.Length >= maxPendingEntries)
{
this.pending = new PendingEntry[pending.Length];
}
else
{
PendingEntry[] destinationArray
= new PendingEntry[pending.Length * 2];
Array.Copy(pending, destinationArray, pending.Length);
this.pending = destinationArray;
}
}
#endregion
}
原文地址:https://www.cnblogs.com/Googler/p/1752243.html