Активный объект
Шаблон активных объектов проектирования отделяет выполнение метода от вызова метода для объектов, каждый из которых находится в своем собственном потоке управления. [1] Цель — внедрить параллелизм , используя асинхронный вызов методов и планировщик для обработки запросов. [2]
Паттерн состоит из шести элементов: [3]
- Прокси , который обеспечивает интерфейс для клиентов с общедоступными методами.
- Интерфейс, определяющий запрос метода для активного объекта.
- Список ожидающих запросов от клиентов.
- Планировщик , который решает , какой запрос выполнить следующим.
- Реализация метода активного объекта.
- или Обратный вызов переменная , позволяющая клиенту получить результат.
Пример
[ редактировать ]Ява
[ редактировать ]Пример шаблона активного объекта в Java . [4]
Во-первых, мы видим стандартный класс, который предоставляет два метода, которые присваивают двойному значению определенное значение. Этот класс НЕ соответствует шаблону активного объекта.
class MyClass {
private double val = 0.0;
void doSomething() {
val = 1.0;
}
void doSomethingElse() {
val = 2.0;
}
}
Этот класс опасен в многопоточном сценарии, поскольку оба метода могут быть вызваны одновременно, поэтому значение val (которое не является атомарным — оно обновляется в несколько этапов) может быть неопределенным — классическое состояние гонки. Конечно, для решения этой проблемы можно использовать синхронизацию, что в этом тривиальном случае легко. Но как только класс станет действительно сложным, синхронизация может стать очень сложной. [5]
Чтобы переписать этот класс как активный объект, вы можете сделать следующее:
class MyActiveObject {
private double val = 0.0;
private BlockingQueue<Runnable> dispatchQueue = new LinkedBlockingQueue<Runnable>();
public MyActiveObject() {
new Thread (new Runnable() {
@Override
public void run() {
try {
while (true) {
dispatchQueue.take().run();
}
} catch (InterruptedException e) {
// okay, just terminate the dispatcher
}
}
}
).start();
}
void doSomething() throws InterruptedException {
dispatchQueue.put(new Runnable() {
@Override
public void run() {
val = 1.0;
}
}
);
}
void doSomethingElse() throws InterruptedException {
dispatchQueue.put(new Runnable() {
@Override
public void run() {
val = 2.0;
}
}
);
}
}
Java 8 (альтернатива)
[ редактировать ]Другой пример шаблона активного объекта в Java, реализованный вместо Java 8, обеспечивает более короткое решение.
public class MyClass {
private double val;
// container for tasks
// decides which request to execute next
// asyncMode=true means our worker thread processes its local task queue in the FIFO order
// only single thread may modify internal state
private final ForkJoinPool fj = new ForkJoinPool(1, ForkJoinPool.defaultForkJoinWorkerThreadFactory, null, true);
// implementation of active object method
public void doSomething() throws InterruptedException {
fj.execute(() -> { val = 1.0; });
}
// implementation of active object method
public void doSomethingElse() throws InterruptedException {
fj.execute(() -> { val = 2.0; });
}
}
См. также
[ редактировать ]- Параллельное объектно-ориентированное программирование
- Модель актера
- Фьючерсы и обещания
- Живой распределенный объект
Ссылки
[ редактировать ]- ^ Дуглас К. Шмидт ; Михаил Сталь; Ганс Ронерт; Фрэнк Бушманн (2000). Шаблонно-ориентированная архитектура программного обеспечения, Том 2: Шаблоны для параллельных и сетевых объектов . Джон Уайли и сыновья. ISBN 0-471-60695-2 .
- ^ Басс, Л., Клементс, П., Казман, Р. Архитектура программного обеспечения на практике . Эддисон Уэсли, 2003 г.
- ^ Лаванда, Р. Грег; Шмидт, Дуглас К. «Активный объект» (PDF) . Архивировано из оригинала (PDF) 22 июля 2012 г. Проверено 2 февраля 2007 г.
- ^ Голуб, Аллен. «Активные объекты Java — предложение» . Архивировано из оригинала 22 июня 2013 г. Проверено 16 июня 2014 г.
- ^ Голуб, Аллен. «Активные объекты Java — предложение» . Архивировано из оригинала 22 июня 2013 г. Проверено 16 июня 2014 г.
Внешние ссылки
[ редактировать ]- Сверхвысокопроизводительное промежуточное программное обеспечение на основе Disruptor Active Object в C++14.
- Реализация активного объекта в C++11