Пул объектов (Object Pool) — различия между версиями
Admin (обсуждение | вклад) (→Описание) |
Admin (обсуждение | вклад) (→Пример) |
||
(не показано 7 промежуточных версий этого же участника) | |||
Строка 5: | Строка 5: | ||
=== Описание === | === Описание === | ||
− | Создание экземпляров некоторого класса может требовать довольно больших затрат. | + | Создание экземпляров некоторого класса может требовать довольно больших затрат. В этом случае решением может быть создание в начале работы программы '''объектного пула''' - набор инициализированных и готовых к использованию объектов. Когда системе требуется объект, он не создаётся, а берётся из пула. |
+ | Когда объект больше не нужен, он не уничтожается, а возвращается в пул. | ||
− | + | Особенно заметно повышение производительности когда объекты часто создаются-уничтожаются, но одновременно существует их небольшое число. | |
− | |||
=== Использование === | === Использование === | ||
+ | Паттерн '''Пул объектов''' используется когда: | ||
+ | * Программа может создать только ограниченное число экземпляров некоторого класса | ||
+ | * Экземпляры класса являются взаимозаменяемыми. Если есть сразу несколько экземпляров, то можно выбрать любой. | ||
+ | * Объект требует значительных ресурсов на свое создание | ||
+ | * Объекты постоянно создаются-уничтожаются и в каждый момент времени используется небольшое их число | ||
=== Реализация === | === Реализация === | ||
==== Диаграмма классов ==== | ==== Диаграмма классов ==== | ||
− | [[Изображение: | + | [[Изображение:ObjectPoolCommon.png]] |
==== Участники==== | ==== Участники==== | ||
− | * | + | *'''Reusable''' - повторно используемый объект |
+ | *'''ReusablePool''' - пул повторно используемых объектов | ||
+ | ReusablePool поддерживает список неиспользуемых объектов Reusable. | ||
+ | Если при вызове метода AcquireReusable в пуле имеются свободные объекты Reusable, то один из них удаляется из списка и возвращается методом. | ||
+ | После завершения работы с объектом Reusable клиент вызывает метод ReleaseReusable, возвращающий объект в список пула | ||
=== Пример === | === Пример === | ||
<source lang="Csharp"> | <source lang="Csharp"> | ||
+ | using System; | ||
+ | using System.Collections.Generic; | ||
+ | using System.Linq; | ||
+ | using System.Text; | ||
+ | using System.Threading.Tasks; | ||
+ | |||
+ | namespace ObjectPool | ||
+ | { | ||
+ | class Reusable | ||
+ | { | ||
+ | } | ||
+ | |||
+ | class ReusablePool | ||
+ | { | ||
+ | private List<Reusable> list = new List<Reusable>(); | ||
+ | |||
+ | public ReusablePool(int n) | ||
+ | { | ||
+ | for (int i = 0; i < n; i++) | ||
+ | list.Add(new Reusable()); | ||
+ | } | ||
+ | |||
+ | public Reusable AcquireReusable() | ||
+ | { | ||
+ | if (list.Count == 0) | ||
+ | return null; | ||
+ | var r = list.First(); | ||
+ | list.Remove(r); | ||
+ | return r; | ||
+ | } | ||
+ | |||
+ | public void ReleaseReusable(Reusable r) | ||
+ | { | ||
+ | list.Add(r); | ||
+ | } | ||
+ | } | ||
+ | class Program | ||
+ | { | ||
+ | static void Main() | ||
+ | { | ||
+ | var Pool = new ReusablePool(3); | ||
+ | |||
+ | var r1 = Pool.AcquireReusable(); | ||
+ | var r2 = Pool.AcquireReusable(); | ||
+ | |||
+ | Pool.ReleaseReusable(r2); | ||
+ | |||
+ | var r3 = Pool.AcquireReusable(); | ||
+ | var r4 = Pool.AcquireReusable(); | ||
+ | |||
+ | Pool.ReleaseReusable(r3); | ||
+ | } | ||
+ | } | ||
+ | } | ||
</source> | </source> | ||
=== Достоинства и недостатки === | === Достоинства и недостатки === | ||
− | * | + | *Централизованное управление ресурсами |
+ | *Отсутствие затрат ресурсов на создание объектов в процессе работы | ||
+ | *Недостаток: после того, как объект возвращён, он должен вернуться в состояние, пригодное для дальнейшего | ||
+ | использования, а для этого может потребоваться дополнительное программирование | ||
+ | *Недостаток: если в объекте есть секретные данные, то после его использования необходимо позаботиться о стирании этих данных | ||
=== Варианты === | === Варианты === | ||
− | * | + | Если в пуле нет ни одного свободного объекта, возможна одна из трёх стратегий: |
+ | *Расширение пула. | ||
+ | *Отказ в создании объекта, аварийный останов. | ||
+ | *В случае многозадачной системы, можно подождать, пока один из объектов не освободится. |
Текущая версия на 08:13, 7 октября 2014
Назначение
Обеспечивает интерфейс для работы с набором инициализированных и готовых к использованию объектов.
Описание
Создание экземпляров некоторого класса может требовать довольно больших затрат. В этом случае решением может быть создание в начале работы программы объектного пула - набор инициализированных и готовых к использованию объектов. Когда системе требуется объект, он не создаётся, а берётся из пула. Когда объект больше не нужен, он не уничтожается, а возвращается в пул.
Особенно заметно повышение производительности когда объекты часто создаются-уничтожаются, но одновременно существует их небольшое число.
Использование
Паттерн Пул объектов используется когда:
- Программа может создать только ограниченное число экземпляров некоторого класса
- Экземпляры класса являются взаимозаменяемыми. Если есть сразу несколько экземпляров, то можно выбрать любой.
- Объект требует значительных ресурсов на свое создание
- Объекты постоянно создаются-уничтожаются и в каждый момент времени используется небольшое их число
Реализация
Диаграмма классов
Участники
- Reusable - повторно используемый объект
- ReusablePool - пул повторно используемых объектов
ReusablePool поддерживает список неиспользуемых объектов Reusable. Если при вызове метода AcquireReusable в пуле имеются свободные объекты Reusable, то один из них удаляется из списка и возвращается методом. После завершения работы с объектом Reusable клиент вызывает метод ReleaseReusable, возвращающий объект в список пула
Пример
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ObjectPool
{
class Reusable
{
}
class ReusablePool
{
private List<Reusable> list = new List<Reusable>();
public ReusablePool(int n)
{
for (int i = 0; i < n; i++)
list.Add(new Reusable());
}
public Reusable AcquireReusable()
{
if (list.Count == 0)
return null;
var r = list.First();
list.Remove(r);
return r;
}
public void ReleaseReusable(Reusable r)
{
list.Add(r);
}
}
class Program
{
static void Main()
{
var Pool = new ReusablePool(3);
var r1 = Pool.AcquireReusable();
var r2 = Pool.AcquireReusable();
Pool.ReleaseReusable(r2);
var r3 = Pool.AcquireReusable();
var r4 = Pool.AcquireReusable();
Pool.ReleaseReusable(r3);
}
}
}
Достоинства и недостатки
- Централизованное управление ресурсами
- Отсутствие затрат ресурсов на создание объектов в процессе работы
- Недостаток: после того, как объект возвращён, он должен вернуться в состояние, пригодное для дальнейшего
использования, а для этого может потребоваться дополнительное программирование
- Недостаток: если в объекте есть секретные данные, то после его использования необходимо позаботиться о стирании этих данных
Варианты
Если в пуле нет ни одного свободного объекта, возможна одна из трёх стратегий:
- Расширение пула.
- Отказ в создании объекта, аварийный останов.
- В случае многозадачной системы, можно подождать, пока один из объектов не освободится.