Активный объект шаблон проектирования разъединяет выполнение метода от вызова метода для объектов , которые выполнены каждый в своем собственном потоке управления. [1] Цель состоит в том, чтобы ввести параллелизм с помощью вызова асинхронных методов и планировщика для обработки запросов. [2]
Паттерн состоит из шести элементов: [3]
- Прокси , который предоставляет интерфейс к клиентам с публично доступными методами.
- Интерфейс, который определяет запрос метода для активного объекта.
- Список ожидающих запросов от клиентов.
- Планировщик , который решает , какой запрос на выполнение следующего.
- Реализация метода активного объекта.
- Обратный вызов или переменный для клиента , чтобы получить результат.
Пример [ править ]
Java [ править ]
Пример шаблона активного объекта в Java . [4]
Во-первых, мы можем увидеть стандартный класс, который предоставляет два метода, которые устанавливают двойное значение как определенное значение. Этот класс НЕ соответствует шаблону активного объекта.
class MyClass { частный двойной вал = 0,0 ; void doSomething () { val = 1.0 ; } void doSomethingElse () { val = 2.0 ; } }
Класс опасен в многопоточном сценарии, потому что оба метода могут быть вызваны одновременно, поэтому значение val (которое не является атомарным - оно обновляется в несколько шагов) может быть неопределенным - классическое состояние гонки. Вы, конечно, можете использовать синхронизацию для решения этой проблемы, что в этом тривиальном случае легко. Но как только класс становится реально сложным, синхронизация может стать очень сложной. [5]
Чтобы переписать этот класс как активный объект, вы можете сделать следующее:
class MyActiveObject { частный двойной вал = 0,0 ; private BlockingQueue < Runnable > dispatchQueue = new LinkedBlockingQueue < Runnable > (); общественный MyActiveObject () { новый Thread ( новый Runnable () { @Override public void run () { while ( true ) { попробуйте { dispatchQueue . взять (). run (); } catch ( InterruptedException e ) { // хорошо, просто завершаем работу диспетчера } } } } ). start (); } void doSomething () выбрасывает InterruptedException { dispatchQueue . put ( new Runnable () { @Override public void run () { val = 1.0 ; } } ); } void doSomethingElse () выбрасывает InterruptedException { dispatchQueue . put ( new Runnable () { @Override public void run () { val = 2.0 ; } } ); } }
Java 8 (альтернатива) [ править ]
Другой пример шаблона активного объекта в Java, реализованный вместо этого в Java 8, обеспечивает более короткое решение.
публичный класс MyClass { частный двойной вал ; // контейнер для задач // решает, какой запрос выполнить следующим // asyncMode = true означает, что наш рабочий поток обрабатывает свою локальную очередь задач в порядке FIFO // только один поток может изменять внутреннее состояние private final ForkJoinPool fj = new ForkJoinPool ( 1 , ForkJoinPool . DefaultForkJoinWorkerThreadFactory , null , true ); // реализация метода активного объекта public void doSomething () выбрасывает InterruptedException { fj . выполнить (() -> { val = 1.0 ; }); } // реализация метода активного объекта public void doSomethingElse () выбрасывает InterruptedException { fj . выполнить (() -> { val = 2.0 ; }); } }
См. Также [ править ]
- Параллельное объектно-ориентированное программирование
- Актерская модель
- Будущее и обещания
- Живой распределенный объект
Ссылки [ править ]
- ^ Дуглас С. Шмидт ; Михаил Сталь; Ганс Ронерт; Фрэнк Бушманн (2000). Шаблонно-ориентированная архитектура программного обеспечения, Том 2: Шаблоны для параллельных и сетевых объектов . Джон Вили и сыновья. ISBN 0-471-60695-2.
- ^ Басс, Л., Клементс, П., Казман, Р. Архитектура программного обеспечения на практике . Эддисон Уэсли, 2003
- ^ Лаванда, Р. Грег; Шмидт, Дуглас К. «Активный объект» (PDF) . Архивировано из оригинального (PDF) 22 июля 2012 года . Проверено 2 февраля 2007 .
- ^ Голуб, Аллен. «Активные объекты Java - предложение» . Архивировано из оригинала на 2013-06-22 . Проверено 16 июня 2014 .
- ^ Голуб, Аллен. «Активные объекты Java - предложение» . Архивировано из оригинала на 2013-06-22 . Проверено 16 июня 2014 .
Внешние ссылки [ править ]
- Сверхвысокопроизводительное промежуточное ПО на основе активного объекта Disruptor в C ++ 14
- Реализация активного объекта в C ++ 11