<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>http://digida.mgpu.ru/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=188.162.4.164</id>
	<title>Поле цифровой дидактики - Вклад [ru]</title>
	<link rel="self" type="application/atom+xml" href="http://digida.mgpu.ru/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=188.162.4.164"/>
	<link rel="alternate" type="text/html" href="http://digida.mgpu.ru/index.php?title=%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/188.162.4.164"/>
	<updated>2026-09-29T22:30:25Z</updated>
	<subtitle>Вклад</subtitle>
	<generator>MediaWiki 1.46.0</generator>
	<entry>
		<id>http://digida.mgpu.ru/index.php?title=%D0%9E%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D0%BD%D1%8B%D0%B9_%D0%BF%D1%83%D0%BB&amp;diff=4488</id>
		<title>Объектный пул</title>
		<link rel="alternate" type="text/html" href="http://digida.mgpu.ru/index.php?title=%D0%9E%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D0%BD%D1%8B%D0%B9_%D0%BF%D1%83%D0%BB&amp;diff=4488"/>
		<updated>2022-07-03T07:11:53Z</updated>

		<summary type="html">&lt;p&gt;188.162.4.164: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{значения|Пул (значения)}}&lt;br /&gt;
{{Шаблон проектирования&lt;br /&gt;
 |название = Объектный пул&lt;br /&gt;
 |английское_название = Object pool&lt;br /&gt;
 |диаграмма =  &lt;br /&gt;
 |тип = порождающий&lt;br /&gt;
 |назначение = &lt;br /&gt;
 |структура = &lt;br /&gt;
 |применяется_в_случаях = &lt;br /&gt;
 |плюсы = &lt;br /&gt;
 |минусы = &lt;br /&gt;
 |родственные_шаблоны = &lt;br /&gt;
 |design_patterns = Нет&lt;br /&gt;
}}&lt;br /&gt;
&#039;&#039;&#039;Объектный пул&#039;&#039;&#039; ({{lang-en|object pool}}) — [[Порождающие шаблоны проектирования|порождающий шаблон проектирования]], набор инициализированных и готовых к использованию объектов. Когда системе требуется объект, он не создаётся, а берётся из пула. Когда объект больше не нужен, он не уничтожается, а возвращается в пул.&lt;br /&gt;
&lt;br /&gt;
== Применение ==&lt;br /&gt;
Объектный пул применяется для повышения производительности, когда создание объекта в начале работы и уничтожение его в конце приводит к большим затратам. Особенно заметно повышение производительности, когда объекты часто создаются-уничтожаются, но одновременно существует лишь небольшое их число.&lt;br /&gt;
&lt;br /&gt;
Объектный пул удобен, если объект владеет другими ресурсами, кроме памяти — например, сетевыми сокетами. Либо если коллекция объектов отнимает значительную часть памяти компьютера и «[[сборка мусора|мусора]]» создаётся действительно много.&lt;br /&gt;
&lt;br /&gt;
== Переполнение ==&lt;br /&gt;
Если в пуле нет ни одного свободного объекта, возможна одна из трёх стратегий:&lt;br /&gt;
# Расширение пула.&lt;br /&gt;
# Отказ в создании объекта, аварийная остановка.&lt;br /&gt;
# В случае [[многозадачность|многозадачной]] системы можно подождать, пока один из объектов не освободится.&lt;br /&gt;
&lt;br /&gt;
== Примеры ==&lt;br /&gt;
# Информация об открытых [[файл]]ах в [[DOS]].&lt;br /&gt;
# Информация о видимых объектах во многих [[компьютерная игра|компьютерных играх]] (хорошим примером является [[движок Doom]]). Эта информация актуальна только в течение одного кадра; после того, как кадр выведен, список опустошается.&lt;br /&gt;
# Компьютерная игра для хранения всех объектов на карте, вместо того, чтобы использовать обычные механизмы распределения памяти, может завести [[массив (программирование)|массив]] такого размера, которого заведомо хватит на все объекты, и свободные ячейки держать в виде [[связный список|связного списка]]. Такая конструкция повышает скорость, уменьшает фрагментацию памяти и снижает нагрузку на [[Сборка мусора (программирование)|сборщик мусора]] (если он есть).&lt;br /&gt;
&lt;br /&gt;
== Ловушки ==&lt;br /&gt;
{{anchor|Объектная_клоака}}&lt;br /&gt;
# После того, как объект возвращён, он должен вернуться в состояние, пригодное для дальнейшего использования. Если объекты после возвращения в пул оказываются в неправильном или неопределённом состоянии, такая конструкция называется &#039;&#039;&#039;объектной клоакой&#039;&#039;&#039; ({{lang-en|object cesspool}}).&lt;br /&gt;
# Повторное использование объектов также может привести к утечке информации. Если в объекте есть секретные данные (например, номер [[кредитная карточка|кредитной карты]]), после освобождения объекта эту информацию надо затереть.&lt;br /&gt;
# Многопоточный объектный пул написать не так просто.&lt;br /&gt;
# На 2020-е годы в языках со сбором мусора управление памятью хорошо оптимизировано под постоянное выделение-отдачу. Так что, если объект занимает только память, руководства по Java не рекомендуют пользоваться пулами: обычный &amp;lt;code&amp;gt;new&amp;lt;/code&amp;gt; требует всего десять процессорных команд. А сборщики мусора часто сканируют ссылки на объекты, а не их память — потому чем больше в памяти «живых» объектов, тем ниже производительность такого сборщика.&lt;br /&gt;
&lt;br /&gt;
== Пример реализации ==&lt;br /&gt;
&lt;br /&gt;
=== Пример на [[Python]] ===&lt;br /&gt;
{{Hider_hiding&lt;br /&gt;
| title = Исходный текст на языке Python&lt;br /&gt;
| content = &lt;br /&gt;
&amp;lt;source lang=&#039;python&#039;&amp;gt; &lt;br /&gt;
#coding: utf-8&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
Представим ситуацию, что у нас есть корабль, который может выдержать несколько выстрелов.&lt;br /&gt;
Создание объекта Shot стоит дорого.&lt;br /&gt;
Поэтому объекты семейства Shot создаём 1 раз.&lt;br /&gt;
А по истечении жизни объект остаётся в памяти.&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
class Shot(object):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Сущность, способная пережить несколько попаданий&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    def __init__(self, lifetime=5):&lt;br /&gt;
        self.lifetime = lifetime&lt;br /&gt;
&lt;br /&gt;
    def update(self):&lt;br /&gt;
        self.lifetime -= 1&lt;br /&gt;
        return self.lifetime &amp;gt; 0&lt;br /&gt;
&lt;br /&gt;
class ObjectPool:&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Пул объектов&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    def __init__(self, **kwargs):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Создание пула&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        self._clsname = kwargs[&#039;classname&#039;]&lt;br /&gt;
        self._args = kwargs.get(&#039;args&#039;, [])&lt;br /&gt;
        self._num_objects = max(kwargs[&#039;num&#039;], 0)&lt;br /&gt;
        self._pred = kwargs[&#039;update_func&#039;]&lt;br /&gt;
        self._max_objects = kwargs.get(&#039;max&#039;, self._num_objects)&lt;br /&gt;
&lt;br /&gt;
        # Create the objects&lt;br /&gt;
        self._objs = [apply(self._clsname, self._args)&lt;br /&gt;
                      for x in range(self._num_objects)]&lt;br /&gt;
        self._end = len(self._objs)&lt;br /&gt;
&lt;br /&gt;
    def _extend_list(self, args):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Добавить одно место в пул&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        self._objs.append(apply(self._clsname, args))&lt;br /&gt;
        self._num_objects += 1&lt;br /&gt;
&lt;br /&gt;
    def add(self, *args):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Добавить один объект в пул&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        newend = self._end + 1&lt;br /&gt;
        # Если достигнут максимум - отбой&lt;br /&gt;
        if newend &amp;gt; self._max_objects:&lt;br /&gt;
            return None&lt;br /&gt;
        # Если заняли все места - добавляем еще одно место&lt;br /&gt;
        if newend &amp;gt; len(self._objs):&lt;br /&gt;
            self._extend_list(args)&lt;br /&gt;
        else:&lt;br /&gt;
            self._objs[self._end].reset(*args)&lt;br /&gt;
        self._end += 1&lt;br /&gt;
        return self._end - 1&lt;br /&gt;
&lt;br /&gt;
    def update(self, *args):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Обновить все объекты в пуле&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        self._end = partition(self._pred, self._objs, 0, self._end, args)&lt;br /&gt;
        return self._end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def update_object(x):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Обновить объект&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    return x.update()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def partition(pred, seq, first, last, *args):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Функция сортировки объектов&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    if first &amp;gt; last:&lt;br /&gt;
        return 0&lt;br /&gt;
&lt;br /&gt;
    for i in range(first, last):&lt;br /&gt;
        if not pred(seq[i]):&lt;br /&gt;
            break&lt;br /&gt;
    else:&lt;br /&gt;
        return last&lt;br /&gt;
&lt;br /&gt;
    for j in range(i+1, last):&lt;br /&gt;
        if pred(seq[j]):&lt;br /&gt;
            seq[i], seq[j] = seq[j], seq[i]&lt;br /&gt;
            i += 1&lt;br /&gt;
    return i&lt;br /&gt;
&lt;br /&gt;
# Собственно использование пула&lt;br /&gt;
shots = ObjectPool(classname=Shot, update_func=update_object, num=5)&lt;br /&gt;
while shots.update():&lt;br /&gt;
    pass&lt;br /&gt;
&lt;br /&gt;
print &amp;quot;Done!&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Пример на [[C++]] ===&lt;br /&gt;
{{Hider_hiding&lt;br /&gt;
| title = Исходный текст на языке C++&lt;br /&gt;
| content =&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;vector&amp;gt;&lt;br /&gt;
&lt;br /&gt;
class Object&lt;br /&gt;
{&lt;br /&gt;
	// ...&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class ObjectPool&lt;br /&gt;
{&lt;br /&gt;
	private:&lt;br /&gt;
		struct PoolRecord&lt;br /&gt;
		{&lt;br /&gt;
			Object* instance;&lt;br /&gt;
			bool    in_use;&lt;br /&gt;
		};&lt;br /&gt;
&lt;br /&gt;
		std::vector&amp;lt;PoolRecord&amp;gt; m_pool;&lt;br /&gt;
&lt;br /&gt;
	public:&lt;br /&gt;
		Object* createNewObject()&lt;br /&gt;
		{&lt;br /&gt;
			for (size_t i = 0; i &amp;lt; m_pool.size(); ++i)&lt;br /&gt;
			{&lt;br /&gt;
				if (! m_pool[i].in_use)&lt;br /&gt;
				{&lt;br /&gt;
					m_pool[i].in_use = true; // переводим объект в список используемых&lt;br /&gt;
					return m_pool[i].instance;&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
			// если не нашли свободный объект, то расширяем пул&lt;br /&gt;
			PoolRecord record;&lt;br /&gt;
			record.instance = new Object;&lt;br /&gt;
			record.in_use   = true;&lt;br /&gt;
&lt;br /&gt;
			m_pool.push_back(record);&lt;br /&gt;
&lt;br /&gt;
			return record.instance;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		void deleteObject(Object* object)&lt;br /&gt;
		{&lt;br /&gt;
			// в реальности не удаляем, а лишь помечаем, что объект свободен&lt;br /&gt;
			for (size_t i = 0; i &amp;lt; m_pool.size(); ++i)&lt;br /&gt;
			{&lt;br /&gt;
				if (m_pool[i].instance == object)&lt;br /&gt;
				{&lt;br /&gt;
					m_pool[i].in_use = false;&lt;br /&gt;
					break;&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		virtual ~ObjectPool()&lt;br /&gt;
		{&lt;br /&gt;
			// теперь уже &amp;quot;по-настоящему&amp;quot; удаляем объекты&lt;br /&gt;
			for (size_t i = 0; i &amp;lt; m_pool.size(); ++i)&lt;br /&gt;
				delete m_pool[i].instance;&lt;br /&gt;
		}&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
	ObjectPool pool;&lt;br /&gt;
	for (size_t i = 0; i &amp;lt; 1000; ++i)&lt;br /&gt;
	{&lt;br /&gt;
		Object* object = pool.createNewObject();&lt;br /&gt;
		// ...&lt;br /&gt;
		pool.deleteObject(object);&lt;br /&gt;
	}&lt;br /&gt;
	return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Из примера для простоты убраны [[Шаблоны C++|шаблоны]] и потокозащищенность. При необходимости использования пула в нескольких потоках следует защитить тело методов createNewObject и deleteObject от одновременного выполнения каким-либо подходящим объектом синхронизации, например, [[Критическая секция|критической секцией]] или [[мьютекс]]ом.&lt;br /&gt;
&lt;br /&gt;
=== Пример на [[C Sharp#|C#]] ===&lt;br /&gt;
{{Hider_hiding&lt;br /&gt;
| title = Исходный текст на языке C#&lt;br /&gt;
| content =&lt;br /&gt;
&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
namespace Digital_Patterns.Creational.Object_Pool.Soft&lt;br /&gt;
{&lt;br /&gt;
    /// &amp;lt;summary&amp;gt;&lt;br /&gt;
    /// Интерфейс для использования шаблона &amp;quot;Object Pool&amp;quot; &amp;lt;see cref=&amp;quot;Object_Pool&amp;quot;/&amp;gt;&lt;br /&gt;
    /// &amp;lt;/summary&amp;gt;&lt;br /&gt;
    /// &amp;lt;typeparam name=&amp;quot;T&amp;quot;&amp;gt;&amp;lt;/typeparam&amp;gt;&lt;br /&gt;
    public interface ICreation&amp;lt;T&amp;gt;&lt;br /&gt;
    {&lt;br /&gt;
        /// &amp;lt;summary&amp;gt;&lt;br /&gt;
        /// Возвращает вновь созданный объект&lt;br /&gt;
        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;
        /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;br /&gt;
        T Create();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
{{Hider_hiding&lt;br /&gt;
| title = Исходный текст на языке C#&lt;br /&gt;
| content =&lt;br /&gt;
&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using System;&lt;br /&gt;
using System.Collections;&lt;br /&gt;
using System.Threading;&lt;br /&gt;
&lt;br /&gt;
namespace Digital_Patterns.Creational.Object_Pool.Soft&lt;br /&gt;
{&lt;br /&gt;
    /// &amp;lt;summary&amp;gt;&lt;br /&gt;
    /// Реализация пула объектов, использующего &amp;quot;мягкие&amp;quot; ссылки&lt;br /&gt;
    /// &amp;lt;/summary&amp;gt;&lt;br /&gt;
    /// &amp;lt;typeparam name=&amp;quot;T&amp;quot;&amp;gt;&amp;lt;/typeparam&amp;gt;&lt;br /&gt;
    public class ObjectPool&amp;lt;T&amp;gt; where T : class&lt;br /&gt;
    {&lt;br /&gt;
        /// &amp;lt;summary&amp;gt;&lt;br /&gt;
        /// Объект синхронизации&lt;br /&gt;
        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;
        private Semaphore semaphore;&lt;br /&gt;
&lt;br /&gt;
        /// &amp;lt;summary&amp;gt;&lt;br /&gt;
        /// Коллекция содержит управляемые объекты&lt;br /&gt;
        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;
        private ArrayList pool;&lt;br /&gt;
&lt;br /&gt;
        /// &amp;lt;summary&amp;gt;&lt;br /&gt;
        /// Ссылка на объект, которому делегируется ответственность &lt;br /&gt;
        /// за создание объектов пула&lt;br /&gt;
        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;
        private ICreation&amp;lt;T&amp;gt; creator;&lt;br /&gt;
&lt;br /&gt;
        /// &amp;lt;summary&amp;gt;&lt;br /&gt;
        /// Количество объектов, существующих в данный момент&lt;br /&gt;
        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;
        private Int32 instanceCount;&lt;br /&gt;
&lt;br /&gt;
        /// &amp;lt;summary&amp;gt;&lt;br /&gt;
        /// Максимальное количество управляемых пулом объектов&lt;br /&gt;
        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;
        private Int32 maxInstances;&lt;br /&gt;
&lt;br /&gt;
        /// &amp;lt;summary&amp;gt;&lt;br /&gt;
        /// Создание пула объектов&lt;br /&gt;
        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;
        /// &amp;lt;param name=&amp;quot;creator&amp;quot;&amp;gt;Объект, которому пул будет делегировать ответственность&lt;br /&gt;
        /// за создание управляемых им объектов&amp;lt;/param&amp;gt;&lt;br /&gt;
        public ObjectPool(ICreation&amp;lt;T&amp;gt; creator)&lt;br /&gt;
            : this(creator, Int32.MaxValue)&lt;br /&gt;
        {&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        /// &amp;lt;summary&amp;gt;&lt;br /&gt;
        /// Создание пула объектов&lt;br /&gt;
        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;
        /// &amp;lt;param name=&amp;quot;creator&amp;quot;&amp;gt;Объект, которому пул будет делегировать ответственность&lt;br /&gt;
        /// за создание управляемых им объектов&amp;lt;/param&amp;gt;&lt;br /&gt;
        /// &amp;lt;param name=&amp;quot;maxInstances&amp;quot;&amp;gt;Максимальное количество экземпляров классов,&lt;br /&gt;
        /// которым пул разрешает существовать одновременно&lt;br /&gt;
        /// &amp;lt;/param&amp;gt;&lt;br /&gt;
        public ObjectPool(ICreation&amp;lt;T&amp;gt; creator, Int32 maxInstances)&lt;br /&gt;
        {&lt;br /&gt;
            this.creator = creator;&lt;br /&gt;
            this.instanceCount = 0;&lt;br /&gt;
            this.maxInstances = maxInstances;&lt;br /&gt;
            this.pool = new ArrayList();&lt;br /&gt;
            this.semaphore = new Semaphore(0, this.maxInstances);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        /// &amp;lt;summary&amp;gt;&lt;br /&gt;
        /// Возвращает количество объектов в пуле, ожидающих повторного&lt;br /&gt;
        /// использования. Реальное количество может быть меньше&lt;br /&gt;
        /// этого значения, поскольку возвращаемая &lt;br /&gt;
        /// величина - это количество &amp;quot;мягких&amp;quot; ссылок в пуле.&lt;br /&gt;
        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;
        public Int32 Size&lt;br /&gt;
        {&lt;br /&gt;
            get&lt;br /&gt;
            {&lt;br /&gt;
                lock(pool)&lt;br /&gt;
                {&lt;br /&gt;
                    return pool.Count;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        /// &amp;lt;summary&amp;gt;&lt;br /&gt;
        /// Возвращает количество управляемых пулом объектов,&lt;br /&gt;
        /// существующих в данный момент&lt;br /&gt;
        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;
        public Int32 InstanceCount { get { return instanceCount; } }&lt;br /&gt;
&lt;br /&gt;
        /// &amp;lt;summary&amp;gt;&lt;br /&gt;
        /// Получить или задать максимальное количество управляемых пулом&lt;br /&gt;
        /// объектов, которым пул разрешает существовать одновременно.&lt;br /&gt;
        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;
        public Int32 MaxInstances&lt;br /&gt;
        {&lt;br /&gt;
            get { return maxInstances; }&lt;br /&gt;
            set { maxInstances = value; }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        /// &amp;lt;summary&amp;gt;&lt;br /&gt;
        /// Возвращает из пула объект. При пустом пуле будет создан&lt;br /&gt;
        /// объект, если количество управляемых пулом объектов не &lt;br /&gt;
        /// больше или равно значению, возвращаемому методом &lt;br /&gt;
        /// &amp;lt;see cref=&amp;quot;ObjectPool{T}.MaxInstances&amp;quot;/&amp;gt;. Если количество управляемых пулом &lt;br /&gt;
        /// объектов превышает это значение, то данный метод возварщает null &lt;br /&gt;
        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;
        /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;br /&gt;
        public T GetObject()&lt;br /&gt;
        {&lt;br /&gt;
            lock(pool)&lt;br /&gt;
            {&lt;br /&gt;
                T thisObject = RemoveObject();&lt;br /&gt;
                if (thisObject != null)&lt;br /&gt;
                    return thisObject;&lt;br /&gt;
&lt;br /&gt;
                if (InstanceCount &amp;lt; MaxInstances)&lt;br /&gt;
                    return CreateObject();&lt;br /&gt;
                &lt;br /&gt;
                return null;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        /// &amp;lt;summary&amp;gt;&lt;br /&gt;
        /// Возвращает из пула объект. При пустом пуле будет создан&lt;br /&gt;
        /// объект, если количество управляемых пулом объектов не &lt;br /&gt;
        /// больше или равно значению, возвращаемому методом &lt;br /&gt;
        /// &amp;lt;see cref=&amp;quot;ObjectPool{T}.MaxInstances&amp;quot;/&amp;gt;. Если количество управляемых пулом &lt;br /&gt;
        /// объектов превышает это значение, то данный метод будет ждать до тех&lt;br /&gt;
        /// пор, пока какой-нибудь объект не станет доступным для&lt;br /&gt;
        /// повторного использования.&lt;br /&gt;
        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;
        /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;br /&gt;
        public T WaitForObject()&lt;br /&gt;
        {&lt;br /&gt;
            lock(pool)&lt;br /&gt;
            {&lt;br /&gt;
                T thisObject = RemoveObject();&lt;br /&gt;
                if (thisObject != null)&lt;br /&gt;
                    return thisObject;&lt;br /&gt;
&lt;br /&gt;
                if (InstanceCount &amp;lt; MaxInstances)&lt;br /&gt;
                    return CreateObject();&lt;br /&gt;
            }&lt;br /&gt;
            semaphore.WaitOne();&lt;br /&gt;
            return WaitForObject();&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        /// &amp;lt;summary&amp;gt;&lt;br /&gt;
        /// Удаляет объект из коллекции пула и возвращает его &lt;br /&gt;
        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;
        /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;br /&gt;
        private T RemoveObject()&lt;br /&gt;
        {&lt;br /&gt;
            while (pool.Count &amp;gt; 0 )&lt;br /&gt;
            {&lt;br /&gt;
                var refThis = (WeakReference) pool[pool.Count - 1];&lt;br /&gt;
                pool.RemoveAt(pool.Count - 1);&lt;br /&gt;
                var thisObject = (T)refThis.Target;&lt;br /&gt;
                if (thisObject != null)&lt;br /&gt;
                    return thisObject;&lt;br /&gt;
                instanceCount--;&lt;br /&gt;
            }&lt;br /&gt;
            return null;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        /// &amp;lt;summary&amp;gt;&lt;br /&gt;
        /// Создать объект, управляемый этим пулом&lt;br /&gt;
        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;
        /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;br /&gt;
        private T CreateObject()&lt;br /&gt;
        {&lt;br /&gt;
            T newObject = creator.Create();&lt;br /&gt;
            instanceCount++;&lt;br /&gt;
            return newObject;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        /// &amp;lt;summary&amp;gt;&lt;br /&gt;
        /// Освобождает объект, помещая его в пул для&lt;br /&gt;
        /// повторного использования&lt;br /&gt;
        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;
        /// &amp;lt;param name=&amp;quot;obj&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;&lt;br /&gt;
        /// &amp;lt;exception cref=&amp;quot;NullReferenceException&amp;quot;&amp;gt;&amp;lt;/exception&amp;gt;&lt;br /&gt;
        public void Release(T obj)&lt;br /&gt;
        {&lt;br /&gt;
            if(obj == null)&lt;br /&gt;
                throw new NullReferenceException();&lt;br /&gt;
            lock(pool)&lt;br /&gt;
            {&lt;br /&gt;
                var refThis = new WeakReference(obj);&lt;br /&gt;
                pool.Add(refThis);&lt;br /&gt;
                semaphore.Release();&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
{{Hider_hiding&lt;br /&gt;
| title = Исходный текст на языке C#&lt;br /&gt;
| content =&lt;br /&gt;
&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
namespace Digital_Patterns.Creational.Object_Pool.Soft&lt;br /&gt;
{&lt;br /&gt;
    public class Reusable&lt;br /&gt;
    {&lt;br /&gt;
        public Object[] Objs { get; protected set; }&lt;br /&gt;
&lt;br /&gt;
        public Reusable(params Object[] objs)&lt;br /&gt;
        {&lt;br /&gt;
            this.Objs = objs;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public class Creator : ICreation&amp;lt;Reusable&amp;gt;&lt;br /&gt;
    {&lt;br /&gt;
        private static Int32 iD = 0;&lt;br /&gt;
&lt;br /&gt;
        public Reusable Create()&lt;br /&gt;
        {&lt;br /&gt;
            ++iD;&lt;br /&gt;
            return new Reusable(iD);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public class ReusablePool : ObjectPool&amp;lt;Reusable&amp;gt;&lt;br /&gt;
    {&lt;br /&gt;
        public ReusablePool()&lt;br /&gt;
            : base(new Creator(), 2)&lt;br /&gt;
        {&lt;br /&gt;
            &lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
{{Hider_hiding&lt;br /&gt;
| title = Исходный текст на языке C#&lt;br /&gt;
| content =&lt;br /&gt;
&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using System;&lt;br /&gt;
using System.Threading;&lt;br /&gt;
using Digital_Patterns.Creational.Object_Pool.Soft;&lt;br /&gt;
&lt;br /&gt;
namespace Digital_Patterns&lt;br /&gt;
{&lt;br /&gt;
    class Program&lt;br /&gt;
    {&lt;br /&gt;
        static void Main(string[] args)&lt;br /&gt;
        {&lt;br /&gt;
            Console.WriteLine(System.Reflection.MethodInfo.GetCurrentMethod().Name);&lt;br /&gt;
            var reusablePool = new ReusablePool();&lt;br /&gt;
&lt;br /&gt;
            var thrd1 = new Thread(Run);&lt;br /&gt;
            var thrd2 = new Thread(Run);&lt;br /&gt;
            var thisObject1 = reusablePool.GetObject();&lt;br /&gt;
            var thisObject2 = reusablePool.GetObject();&lt;br /&gt;
            thrd1.Start(reusablePool);&lt;br /&gt;
            thrd2.Start(reusablePool);&lt;br /&gt;
            ViewObject(thisObject1);&lt;br /&gt;
            ViewObject(thisObject2);&lt;br /&gt;
            Thread.Sleep(2000);&lt;br /&gt;
            reusablePool.Release(thisObject1);&lt;br /&gt;
            Thread.Sleep(2000);&lt;br /&gt;
            reusablePool.Release(thisObject2);&lt;br /&gt;
&lt;br /&gt;
            Console.ReadKey();&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        private static void Run(Object obj)&lt;br /&gt;
        {&lt;br /&gt;
            Console.WriteLine(&amp;quot;\t&amp;quot; + System.Reflection.MethodInfo.GetCurrentMethod().Name);&lt;br /&gt;
            var reusablePool = (ReusablePool)obj;&lt;br /&gt;
            Console.WriteLine(&amp;quot;\tstart wait&amp;quot;);&lt;br /&gt;
            var thisObject1 = reusablePool.WaitForObject();&lt;br /&gt;
            ViewObject(thisObject1);&lt;br /&gt;
            Console.WriteLine(&amp;quot;\tend wait&amp;quot;);&lt;br /&gt;
            reusablePool.Release(thisObject1);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        private static void ViewObject(Reusable thisObject)&lt;br /&gt;
        {&lt;br /&gt;
            foreach (var obj in thisObject.Objs)&lt;br /&gt;
            {&lt;br /&gt;
                Console.Write(obj.ToString() + @&amp;quot; &amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            Console.WriteLine();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Пример на [[VB.NET]] ===&lt;br /&gt;
{{Hider_hiding&lt;br /&gt;
| title = Исходный текст на языке VB.NET&lt;br /&gt;
| content =&lt;br /&gt;
&amp;lt;source lang=&amp;quot;vbnet&amp;quot;&amp;gt;&lt;br /&gt;
Namespace Digital_Patterns.Creational.Object_Pool.Soft&lt;br /&gt;
&lt;br /&gt;
    &#039; Интерфейс для использования шаблона &amp;quot;Object Pool&amp;quot; &amp;lt;see cref=&amp;quot;Object_Pool&amp;quot;/&amp;gt;&lt;br /&gt;
    Public Interface ICreation(Of T)&lt;br /&gt;
        &#039; Возвращает вновь созданный объект&lt;br /&gt;
        Function Create() As T&lt;br /&gt;
    End Interface&lt;br /&gt;
&lt;br /&gt;
End Namespace&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
{{Hider_hiding&lt;br /&gt;
| title = Исходный текст на языке VB.NET&lt;br /&gt;
| content =&lt;br /&gt;
&amp;lt;source lang=&amp;quot;vbnet&amp;quot;&amp;gt;&lt;br /&gt;
Namespace Digital_Patterns.Creational.Object_Pool.Soft&lt;br /&gt;
&lt;br /&gt;
    &#039;Реализация пула объектов, использующий &amp;quot;мягкие&amp;quot; ссылки&lt;br /&gt;
    Public Class ObjectPool(Of T As Class)&lt;br /&gt;
&lt;br /&gt;
        &#039;Объект синхронизации&lt;br /&gt;
        Private semaphore As Semaphore&lt;br /&gt;
&lt;br /&gt;
        &#039;Коллекция содержит управляемые объекты&lt;br /&gt;
        Private pool As ArrayList&lt;br /&gt;
&lt;br /&gt;
        &#039;Ссылка на объект, которому делегируется ответственность за создание объектов пула&lt;br /&gt;
        Private creator As ICreation(Of T)&lt;br /&gt;
&lt;br /&gt;
        &#039;Количество объектов, существующих в данный момент&lt;br /&gt;
        Private m_instanceCount As Int32&lt;br /&gt;
&lt;br /&gt;
        &#039;Максимальное количество управляемых пулом объектов&lt;br /&gt;
        Private m_maxInstances As Int32&lt;br /&gt;
&lt;br /&gt;
        &#039;Созданчие пула объектов&lt;br /&gt;
        &#039;  creator - объект, которому пул будет делегировать ответственность за создание управляемых им объектов&lt;br /&gt;
        Public Sub New(ByVal creator As ICreation(Of T))&lt;br /&gt;
            Me.New(creator, Int32.MaxValue)&lt;br /&gt;
        End Sub&lt;br /&gt;
&lt;br /&gt;
        &#039;Создание пула объектов&lt;br /&gt;
        &#039;  creator - Объект, которому пул будет делегировать ответственность за создание управляемых им объектов&lt;br /&gt;
        &#039;  maxInstances - Максимальное количество экземпляров класс, которым пул разрешает существовать одновременно&lt;br /&gt;
        Public Sub New(ByVal creator As ICreation(Of T), ByVal maxInstances As Int32)&lt;br /&gt;
            Me.creator = creator&lt;br /&gt;
            Me.m_instanceCount = 0&lt;br /&gt;
            Me.m_maxInstances = maxInstances&lt;br /&gt;
            Me.pool = New ArrayList()&lt;br /&gt;
            Me.semaphore = New Semaphore(0, Me.m_maxInstances)&lt;br /&gt;
        End Sub&lt;br /&gt;
&lt;br /&gt;
        &#039;Возвращает количество объектов в пуле, ожидающих повторного&lt;br /&gt;
        &#039;использования. Реальное количество может быть меньше&lt;br /&gt;
        &#039;этого значения, поскольку возвращаемая &lt;br /&gt;
        &#039;величина - это количество &amp;quot;мягких&amp;quot; ссылок в пуле.&lt;br /&gt;
        Public ReadOnly Property Size() As Int32&lt;br /&gt;
            Get&lt;br /&gt;
                SyncLock pool&lt;br /&gt;
                    Return pool.Count&lt;br /&gt;
                End SyncLock&lt;br /&gt;
            End Get&lt;br /&gt;
        End Property&lt;br /&gt;
&lt;br /&gt;
        &#039;Возвращает количество управляемых пулом объектов,&lt;br /&gt;
        &#039;существующих в данный момент&lt;br /&gt;
        Public ReadOnly Property InstanceCount() As Int32&lt;br /&gt;
            Get&lt;br /&gt;
                Return m_instanceCount&lt;br /&gt;
            End Get&lt;br /&gt;
        End Property&lt;br /&gt;
&lt;br /&gt;
        &#039;Получить или задать максимальное количество управляемых пулом&lt;br /&gt;
        &#039;объектов, которым пул разрешает существовать одновременно.&lt;br /&gt;
        Public Property MaxInstances() As Int32&lt;br /&gt;
            Get&lt;br /&gt;
                Return m_maxInstances&lt;br /&gt;
            End Get&lt;br /&gt;
            Set(ByVal value As Int32)&lt;br /&gt;
                m_maxInstances = value&lt;br /&gt;
            End Set&lt;br /&gt;
        End Property&lt;br /&gt;
&lt;br /&gt;
        &#039;Возвращает из пула объект. При пустом пуле будет создан&lt;br /&gt;
        &#039;объект, если количество управляемых пулом объектов не &lt;br /&gt;
        &#039;больше или равно значению, возвращаемому методом ObjectPool{T}.MaxInstances.&lt;br /&gt;
        &#039;Если количество управляемых пулом объектов превышает это значение, то данный&lt;br /&gt;
        &#039;метод возварщает null &lt;br /&gt;
        Public Function GetObject() As T&lt;br /&gt;
            SyncLock pool&lt;br /&gt;
                Dim thisObject As T = RemoveObject()&lt;br /&gt;
                If thisObject IsNot Nothing Then&lt;br /&gt;
                    Return thisObject&lt;br /&gt;
                End If&lt;br /&gt;
&lt;br /&gt;
                If InstanceCount &amp;lt; MaxInstances Then&lt;br /&gt;
                    Return CreateObject()&lt;br /&gt;
                End If&lt;br /&gt;
&lt;br /&gt;
                Return Nothing&lt;br /&gt;
            End SyncLock&lt;br /&gt;
        End Function&lt;br /&gt;
&lt;br /&gt;
        &#039; Возвращает из пула объект. При пустом пуле будет создан&lt;br /&gt;
        &#039; объект, если количество управляемых пулом объектов не &lt;br /&gt;
        &#039; больше или равно значению, возвращаемому методом ObjectPool{T}.MaxInstances&lt;br /&gt;
        &#039; Если количество управляемых пулом объектов превышает это значение,&lt;br /&gt;
        &#039; то данный метод будет ждать до тех пор, пока какой-нибудь объект&lt;br /&gt;
        &#039; не станет доступным для повторного использования.&lt;br /&gt;
        Public Function WaitForObject() As T&lt;br /&gt;
            SyncLock pool&lt;br /&gt;
                Dim thisObject As T = RemoveObject()&lt;br /&gt;
                If thisObject IsNot Nothing Then&lt;br /&gt;
                    Return thisObject&lt;br /&gt;
                End If&lt;br /&gt;
&lt;br /&gt;
                If InstanceCount &amp;lt; MaxInstances Then&lt;br /&gt;
                    Return CreateObject()&lt;br /&gt;
                End If&lt;br /&gt;
            End SyncLock&lt;br /&gt;
            semaphore.WaitOne()&lt;br /&gt;
            Return WaitForObject()&lt;br /&gt;
        End Function&lt;br /&gt;
&lt;br /&gt;
        &#039; Удаляет объект из коллекции пула и возвращает его &lt;br /&gt;
        Private Function RemoveObject() As T&lt;br /&gt;
            While pool.Count &amp;gt; 0&lt;br /&gt;
                Dim refThis = DirectCast(pool(pool.Count - 1), WeakReference)&lt;br /&gt;
                pool.RemoveAt(pool.Count - 1)&lt;br /&gt;
                Dim thisObject = DirectCast(refThis.Target, T)&lt;br /&gt;
                If thisObject IsNot Nothing Then&lt;br /&gt;
                    Return thisObject&lt;br /&gt;
                End If&lt;br /&gt;
                m_instanceCount -= 1&lt;br /&gt;
            End While&lt;br /&gt;
            Return Nothing&lt;br /&gt;
        End Function&lt;br /&gt;
&lt;br /&gt;
        &#039; Создать объект, управляемый этим пулом&lt;br /&gt;
        Private Function CreateObject() As T&lt;br /&gt;
            Dim newObject As T = creator.Create()&lt;br /&gt;
            m_instanceCount += 1&lt;br /&gt;
            Return newObject&lt;br /&gt;
        End Function&lt;br /&gt;
&lt;br /&gt;
        &#039; Освобождает объект, помещая его в пул для повторного использования&lt;br /&gt;
        Public Sub Release(ByVal obj As T)&lt;br /&gt;
            If obj Is Nothing Then&lt;br /&gt;
                Throw New NullReferenceException()&lt;br /&gt;
            End If&lt;br /&gt;
            SyncLock pool&lt;br /&gt;
                Dim refThis = New WeakReference(obj)&lt;br /&gt;
                pool.Add(refThis)&lt;br /&gt;
                semaphore.Release()&lt;br /&gt;
            End SyncLock&lt;br /&gt;
        End Sub&lt;br /&gt;
    End Class&lt;br /&gt;
End Namespace&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
{{Hider_hiding&lt;br /&gt;
| title = Исходный текст на языке VB.NET&lt;br /&gt;
| content =&lt;br /&gt;
&amp;lt;source lang=&amp;quot;vbnet&amp;quot;&amp;gt;&lt;br /&gt;
Namespace Digital_Patterns.Creational.Object_Pool.Soft&lt;br /&gt;
&lt;br /&gt;
    &#039;###   Класс Reusable   ####&lt;br /&gt;
    Public Class Reusable&lt;br /&gt;
&lt;br /&gt;
        Private m_Objs As Object()&lt;br /&gt;
&lt;br /&gt;
        Public Sub New(ByVal ParamArray objs As Object())&lt;br /&gt;
            Me.Objs = objs&lt;br /&gt;
        End Sub&lt;br /&gt;
&lt;br /&gt;
        Public Property Objs() As Object()&lt;br /&gt;
            Get&lt;br /&gt;
                Return m_Objs&lt;br /&gt;
            End Get&lt;br /&gt;
&lt;br /&gt;
            Protected Set(ByVal value As Object())&lt;br /&gt;
                m_Objs = value&lt;br /&gt;
            End Set&lt;br /&gt;
        End Property&lt;br /&gt;
    End Class&lt;br /&gt;
&lt;br /&gt;
    &#039;###   Класс Creator   ####&lt;br /&gt;
    Public Class Creator&lt;br /&gt;
        Implements ICreation(Of Reusable)&lt;br /&gt;
&lt;br /&gt;
        Private Shared iD As Int32 = 0&lt;br /&gt;
&lt;br /&gt;
        Public Function Create() As Reusable Implements ICreation(Of Reusable).Create&lt;br /&gt;
            iD += 1&lt;br /&gt;
            Return New Reusable(iD)&lt;br /&gt;
        End Function&lt;br /&gt;
    End Class&lt;br /&gt;
&lt;br /&gt;
    &#039;###   Класс ReusablePool   ####&lt;br /&gt;
    Public Class ReusablePool&lt;br /&gt;
        Inherits ObjectPool(Of Reusable)&lt;br /&gt;
&lt;br /&gt;
        Public Sub New()&lt;br /&gt;
            MyBase.New(New Creator(), 2)&lt;br /&gt;
        End Sub&lt;br /&gt;
    End Class&lt;br /&gt;
End Namespace&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
{{Hider_hiding&lt;br /&gt;
| title = Исходный текст на языке VB.NET&lt;br /&gt;
| content =&lt;br /&gt;
&amp;lt;source lang=&amp;quot;vbnet&amp;quot;&amp;gt;&lt;br /&gt;
Imports System.Threading&lt;br /&gt;
Imports Digital_Patterns.Creational.Object_Pool.Soft&lt;br /&gt;
&lt;br /&gt;
Namespace Digital_Patterns&lt;br /&gt;
    Class Program&lt;br /&gt;
&lt;br /&gt;
        Shared Sub Main()&lt;br /&gt;
            Console.WriteLine(System.Reflection.MethodInfo.GetCurrentMethod().Name)&lt;br /&gt;
            Dim reusablePool = New ReusablePool()&lt;br /&gt;
&lt;br /&gt;
            Dim thrd1 = New Thread(AddressOf Run)&lt;br /&gt;
            Dim thrd2 = New Thread(AddressOf Run)&lt;br /&gt;
            Dim thisObject1 = reusablePool.GetObject()&lt;br /&gt;
            Dim thisObject2 = reusablePool.GetObject()&lt;br /&gt;
&lt;br /&gt;
            thrd1.Start(reusablePool)&lt;br /&gt;
            thrd2.Start(reusablePool)&lt;br /&gt;
&lt;br /&gt;
            ViewObject(thisObject1)&lt;br /&gt;
            ViewObject(thisObject2)&lt;br /&gt;
&lt;br /&gt;
            Thread.Sleep(2000)&lt;br /&gt;
            reusablePool.Release(thisObject1)&lt;br /&gt;
&lt;br /&gt;
            Thread.Sleep(2000)&lt;br /&gt;
            reusablePool.Release(thisObject2)&lt;br /&gt;
&lt;br /&gt;
            Console.ReadKey()&lt;br /&gt;
        End Sub&lt;br /&gt;
&lt;br /&gt;
        Private Shared Sub Run(ByVal obj As [Object])&lt;br /&gt;
            Console.WriteLine(vbTab &amp;amp; System.Reflection.MethodInfo.GetCurrentMethod().Name)&lt;br /&gt;
            Dim reusablePool = DirectCast(obj, ReusablePool)&lt;br /&gt;
&lt;br /&gt;
            Console.WriteLine(vbTab &amp;amp; &amp;quot;start wait&amp;quot;)&lt;br /&gt;
            Dim thisObject1 = reusablePool.WaitForObject()&lt;br /&gt;
&lt;br /&gt;
            ViewObject(thisObject1)&lt;br /&gt;
            Console.WriteLine(vbTab &amp;amp; &amp;quot;end wait&amp;quot;)&lt;br /&gt;
            reusablePool.Release(thisObject1)&lt;br /&gt;
        End Sub&lt;br /&gt;
&lt;br /&gt;
        Private Shared Sub ViewObject(ByVal thisObject As Reusable)&lt;br /&gt;
            For Each obj As Object In thisObject.Objs&lt;br /&gt;
                Console.Write(obj.ToString() &amp;amp; &amp;quot; &amp;quot;)&lt;br /&gt;
            Next&lt;br /&gt;
            Console.WriteLine()&lt;br /&gt;
        End Sub&lt;br /&gt;
    End Class&lt;br /&gt;
End Namespace&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Пример на [[Perl]] ===&lt;br /&gt;
{{Hider_hiding&lt;br /&gt;
| title = Исходный текст на языке Perl&lt;br /&gt;
| content = &lt;br /&gt;
&amp;lt;source lang=&#039;perl&#039;&amp;gt; &lt;br /&gt;
#!/usr/bin/perl -w&lt;br /&gt;
&lt;br /&gt;
=for comment&lt;br /&gt;
&lt;br /&gt;
Модуль ObjectPool реализовывает паттерн программирования &amp;quot;объектный пул&amp;quot; путём моделирования&lt;br /&gt;
поведения лучника, в колчане у которого имеется ограниченное количество стрел, в результате&lt;br /&gt;
чего ему приходится периодически их подбирать&lt;br /&gt;
&lt;br /&gt;
Пакет описывает поведение лучника&lt;br /&gt;
&lt;br /&gt;
=cut&lt;br /&gt;
&lt;br /&gt;
package Archer {&lt;br /&gt;
    &lt;br /&gt;
    use Quiver;     # колчан с стрелами лучника&lt;br /&gt;
    &lt;br /&gt;
    use strict;&lt;br /&gt;
    use warnings;&lt;br /&gt;
    &lt;br /&gt;
    use constant    ARROWS_NUMBER   =&amp;gt;  5;  # количество стрел в колчане&lt;br /&gt;
    use constant    SLEEP_TIME      =&amp;gt;  3;  # максимальный перерыв между двумя действиями (в секундах)&lt;br /&gt;
    &lt;br /&gt;
    # -- ** констркутор ** --&lt;br /&gt;
    sub new {&lt;br /&gt;
        my $class = shift;&lt;br /&gt;
        my $self = {&lt;br /&gt;
            quiver =&amp;gt; Quiver-&amp;gt;new(ARROWS_NUMBER),   # объект класса &amp;quot;Колчан&amp;quot;&lt;br /&gt;
        };&lt;br /&gt;
        bless $self, $class;&lt;br /&gt;
        return $self;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    # -- ** инициализация стрельбы ** --&lt;br /&gt;
    sub shooting_start {&lt;br /&gt;
        my($self) = (shift);&lt;br /&gt;
        while (1) {     # условно бесконечный цикл, в котором ведется стрельба&lt;br /&gt;
            $self-&amp;gt;shoot() for (0 .. rand(ARROWS_NUMBER - 1));  # случайное количество выстрелов&lt;br /&gt;
            $self-&amp;gt;reload() for (0 .. rand(ARROWS_NUMBER - 1)); # случайное количество возвратов отстреляных стрел&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    # -- ** выстрел ** --&lt;br /&gt;
    sub shoot {&lt;br /&gt;
        my($self) = (shift);&lt;br /&gt;
        $self-&amp;gt;{quiver}-&amp;gt;arrow_pull();  # отправляем стрелу куда подальше&lt;br /&gt;
        sleep rand(SLEEP_TIME);         # ... и пребываем в ожидании на протяжении неопределенного промежутка времени&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    # -- ** возвращение выпущеной стрелы ** --&lt;br /&gt;
    sub reload {&lt;br /&gt;
        my($self) = (shift);&lt;br /&gt;
        $self-&amp;gt;{quiver}-&amp;gt;arrow_return();    # возвращаем выпущенную ранее стрелу&lt;br /&gt;
        sleep rand(SLEEP_TIME);             # и опять находимся в ожидании&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
$archer = Archer-&amp;gt;new();    # бравый стрелок берет свой колчан со стрелами&lt;br /&gt;
$archer-&amp;gt;shooting_start();  # ... и начинает стрелять&lt;br /&gt;
&lt;br /&gt;
=for comment&lt;br /&gt;
&lt;br /&gt;
Пакет описывает свойства колчана, которым пользуется лучник (Archer) и в котором хранятся стрелы (Arrow)&lt;br /&gt;
&lt;br /&gt;
=cut&lt;br /&gt;
&lt;br /&gt;
package Quiver {&lt;br /&gt;
&lt;br /&gt;
    use Arrow;      # одна стрела из колчана&lt;br /&gt;
&lt;br /&gt;
    use feature &amp;quot;say&amp;quot;;&lt;br /&gt;
    use strict;&lt;br /&gt;
    use warnings;&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
    # -- ** конструктор ** --&lt;br /&gt;
    sub new {&lt;br /&gt;
        my($class, $arrows_number) = (shift, shift);&lt;br /&gt;
        my $self = {&lt;br /&gt;
            arrows =&amp;gt; [],   # стрелы в колчане (их пока нет, но скоро они там появятся)&lt;br /&gt;
        };&lt;br /&gt;
        bless $self, $class;&lt;br /&gt;
        $self-&amp;gt;arrows_prepare($arrows_number);  # загрузить стрелы в колчан&lt;br /&gt;
        return $self;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    # -- ** приготовление стрел к стрельбе ** --&lt;br /&gt;
    sub arrows_prepare {&lt;br /&gt;
        my($self, $arrows_number) = (shift, shift);&lt;br /&gt;
        push @{$self-&amp;gt;{arrows}}, Arrow-&amp;gt;new($_) for (0 .. $arrows_number - 1);  # укладываем стрелы в колчан&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    # -- ** извлечение стрелы из колчана ** --&lt;br /&gt;
    sub arrow_pull {&lt;br /&gt;
        my($self) = (shift);&lt;br /&gt;
        foreach(@{$self-&amp;gt;{arrows}}) {   # для каждой стрелы проверяем, в колчане ли она&lt;br /&gt;
            if($_-&amp;gt;check_state()) {     # и если - да&lt;br /&gt;
                $_-&amp;gt;pull();             # вынимаем её оттуда (и стреляем)&lt;br /&gt;
                last;                   # двумя стрелами одновременно мы выстрелить не сможем&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    # -- ** возвращение стрелы в колчан ** --&lt;br /&gt;
    sub arrow_return {&lt;br /&gt;
        my($self) = (shift);&lt;br /&gt;
        foreach(@{$self-&amp;gt;{arrows}}) {   # для каждой стрелы проверяем, не выпущена ли она уже&lt;br /&gt;
            if(!$_-&amp;gt;check_state()) {    # если в колчане такой стрелы нет&lt;br /&gt;
                $_-&amp;gt;return();           # идем и подбираем её&lt;br /&gt;
                last;                   # в теории лучник может подобрать больше одной стрелы за раз, но автор считает иначе&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
1;&lt;br /&gt;
&lt;br /&gt;
=for comment&lt;br /&gt;
&lt;br /&gt;
Пакет описывает свойства одной отдельной стрелы, находящейся в колчане (Quiver) лучника (Archer)&lt;br /&gt;
&lt;br /&gt;
=cut&lt;br /&gt;
&lt;br /&gt;
package Arrow {&lt;br /&gt;
&lt;br /&gt;
    use feature &amp;quot;say&amp;quot;;&lt;br /&gt;
    use strict;&lt;br /&gt;
    use warnings;&lt;br /&gt;
    &lt;br /&gt;
    # -- ** конструктор ** --&lt;br /&gt;
    sub new {&lt;br /&gt;
        my $class = shift;&lt;br /&gt;
        my $self = {&lt;br /&gt;
            number =&amp;gt; shift,    # номер стрелы&lt;br /&gt;
            state =&amp;gt; 1,         # состояние стрелы (1 = в колчане, 0 = где-то валяется после выстрела)&lt;br /&gt;
        };&lt;br /&gt;
        bless $self, $class;&lt;br /&gt;
        return $self;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    # -- ** изъять стрелу из колчана ** --&lt;br /&gt;
    sub pull {&lt;br /&gt;
        my($self) = (shift);&lt;br /&gt;
        $self-&amp;gt;{state} = 0;             # изменить состояние стрелы на &amp;quot;выпущена&amp;quot;&lt;br /&gt;
        say &amp;quot;pulled $self-&amp;gt;{number}&amp;quot;;   # сообщить о том, что выстрел состоялся&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    # -- ** вернуть стрелу обратно в колчан ** --&lt;br /&gt;
    sub return {&lt;br /&gt;
        my($self) = (shift);&lt;br /&gt;
        $self-&amp;gt;{state} = 1;             # изменить состояние стрелы на &amp;quot;в колчане&amp;quot;&lt;br /&gt;
        say &amp;quot;returned $self-&amp;gt;{number}&amp;quot;; # сообщить о том, что стрела вернулась к лучнику&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    # -- ** проверить состояние стрелы ** --&lt;br /&gt;
    sub check_state {&lt;br /&gt;
        my($self) = (shift);&lt;br /&gt;
        return $self-&amp;gt;{state};          # вернуть состояние стрелы (1 = в колчане, 0 = выпущена)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
1;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* [http://cpp-reference.ru/patterns/creational-patterns/object-pool/ Паттерн Object Pool (пул объектов)] — назначение, описание, структура, особенности применения&lt;br /&gt;
&lt;br /&gt;
{{Типы Паттернов}}&lt;br /&gt;
&lt;br /&gt;
[[Категория:Структуры данных]]&lt;br /&gt;
[[Категория:Статьи с примерами кода Python]]&lt;/div&gt;</summary>
		<author><name>188.162.4.164</name></author>
	</entry>
</feed>