饭太稀
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
#if !FANTASY_WEBGL
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Runtime.CompilerServices;
|
||||
#pragma warning disable CS8603 // Possible null reference return.
|
||||
|
||||
namespace Fantasy.Pool
|
||||
{
|
||||
/// <summary>
|
||||
/// 线程安全的静态通用对象池。
|
||||
/// </summary>
|
||||
internal static class MultiThreadPool
|
||||
{
|
||||
private static readonly ConcurrentDictionary<Type, MultiThreadPoolQueue> ObjectPools = new ConcurrentDictionary<Type, MultiThreadPoolQueue>();
|
||||
|
||||
public static T Rent<T>() where T : IPool, new()
|
||||
{
|
||||
return ObjectPools.GetOrAdd(typeof(T), t => new MultiThreadPoolQueue(2000, () => new T())).Rent<T>();
|
||||
}
|
||||
|
||||
public static IPool Rent(Type type)
|
||||
{
|
||||
return ObjectPools.GetOrAdd(type, t => new MultiThreadPoolQueue(2000, CreateInstance.CreateIPool(type))).Rent();
|
||||
}
|
||||
|
||||
public static void Return<T>(T obj) where T : IPool, new()
|
||||
{
|
||||
if (!obj.IsPool())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ObjectPools.GetOrAdd(typeof(T), t => new MultiThreadPoolQueue(2000, () => new T())).Return(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,76 @@
|
||||
#if !FANTASY_WEBGL
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Threading;
|
||||
// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract
|
||||
#pragma warning disable CS8601 // Possible null reference assignment.
|
||||
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
||||
#pragma warning disable CS8603 // Possible null reference return.
|
||||
|
||||
namespace Fantasy.Pool
|
||||
{
|
||||
/// <summary>
|
||||
/// 线程安全的对象池。
|
||||
/// </summary>
|
||||
internal class MultiThreadPoolQueue
|
||||
{
|
||||
private int _poolCount;
|
||||
private readonly int _maxCapacity;
|
||||
private readonly Func<IPool> _createInstance;
|
||||
private readonly ConcurrentQueue<IPool> _poolQueue = new ConcurrentQueue<IPool>();
|
||||
private MultiThreadPoolQueue() { }
|
||||
|
||||
public MultiThreadPoolQueue(int maxCapacity, Func<IPool> createInstance)
|
||||
{
|
||||
_maxCapacity = maxCapacity;
|
||||
_createInstance = createInstance;
|
||||
}
|
||||
|
||||
public T Rent<T>() where T : IPool, new()
|
||||
{
|
||||
if (!_poolQueue.TryDequeue(out var t))
|
||||
{
|
||||
var pool = new T();
|
||||
pool.SetIsPool(true);
|
||||
return pool;
|
||||
}
|
||||
|
||||
t.SetIsPool(true);
|
||||
Interlocked.Decrement(ref _poolCount);
|
||||
return (T)t;
|
||||
}
|
||||
|
||||
public IPool Rent()
|
||||
{
|
||||
if (!_poolQueue.TryDequeue(out var t))
|
||||
{
|
||||
var instance = _createInstance();
|
||||
instance.SetIsPool(true);
|
||||
return instance;
|
||||
}
|
||||
|
||||
t.SetIsPool(true);
|
||||
Interlocked.Decrement(ref _poolCount);
|
||||
return t;
|
||||
}
|
||||
|
||||
public void Return(IPool obj)
|
||||
{
|
||||
if (!obj.IsPool())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
obj.SetIsPool(false);
|
||||
|
||||
if (Interlocked.Increment(ref _poolCount) <= _maxCapacity)
|
||||
{
|
||||
_poolQueue.Enqueue(obj);
|
||||
return;
|
||||
}
|
||||
|
||||
Interlocked.Decrement(ref _poolCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user