Created
November 2, 2012 13:24
-
-
Save ujentus/4001356 to your computer and use it in GitHub Desktop.
Object Pool Sample
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Threading; | |
using System.Collections.Concurrent; | |
#pragma warning disable 0420 | |
namespace ObjectPoolSample | |
{ | |
public class ObjectPool<T> where T : class | |
{ | |
private readonly ConcurrentQueue<object> mObjectQueue = new ConcurrentQueue<object>() ; | |
/// 풀에 존재해야 되는 최소한의 하드레퍼런스 객체수 (적당히 찍으삼) | |
private volatile int mMinHardRefSize = 1000 ; | |
/// 현재 큐에 들어있는 하드레퍼런스 객체 수 | |
private volatile int mCurrentHardRefCount = 0 ; | |
/// 오브젝트 생성 함수 포인터 | |
private readonly Func<T> mCreateObjectFunctor ; | |
public int MinimumSize | |
{ | |
get { return mMinHardRefSize ; } | |
set { mMinHardRefSize = value ; } | |
} | |
public int AvailableCount | |
{ | |
get { return mObjectQueue.Count ; } | |
} | |
/// Constructor | |
public ObjectPool(Func<T> func) | |
{ | |
mCreateObjectFunctor = func ; | |
} | |
/// 반납 | |
public void Push(T obj) | |
{ | |
if (mCurrentHardRefCount >= mMinHardRefSize) | |
{ | |
mObjectQueue.Enqueue(new WeakReference(obj)) ; | |
} | |
else | |
{ | |
mObjectQueue.Enqueue(obj); | |
Interlocked.Increment(ref mCurrentHardRefCount) ; | |
} | |
} | |
/// 획득 | |
public T Pop() | |
{ | |
object obj; | |
if (!mObjectQueue.TryDequeue(out obj)) | |
{ | |
return mCreateObjectFunctor() ; | |
} | |
if (obj is WeakReference) | |
{ | |
var robj = ((WeakReference)obj).Target ; | |
if (robj != null) | |
{ | |
/// 하드레퍼런스 객체로 바꿔서 제공 | |
return robj as T ; | |
} | |
/// 이경우는 GC 당해버린 경우다. 리커시브하게 될때까지 고고 | |
return Pop() ; | |
} | |
else | |
{ | |
Interlocked.Decrement(ref mCurrentHardRefCount); | |
return obj as T ; | |
} | |
} | |
} | |
} | |
#pragma warning restore 0420 | |
namespace ObjectPoolSample | |
{ | |
class TestObject | |
{ | |
public TestObject() | |
{ | |
mData = -1; | |
} | |
public TestObject(int data) | |
{ | |
mData = data; | |
} | |
public int mData; | |
} | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
/// 대충 아래와 같이 쓰면됨. 멀티쓰레드 지원 ^^ | |
ObjectPool<TestObject> objPool = new ObjectPool<TestObject>( () => new TestObject() ); | |
} | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment