Активний об'єкт
Активний об'єкт (англ. Active object) — шаблон проектування, який відокремлює виконання методу від виклику методу для об'єктів, кожен з яких знаходиться у власному потоці керування.[1] Мета полягає в тому, щоб запровадити паралелізм за допомогою асинхронного виклику методів і планувальника для обробки запитів.[2]
Шаблон складається з шести елементів:[3]
- Об'єкт-замісник (проксі), який забезпечує інтерфейс для клієнтів із загальнодоступними методами.
- Інтерфейс, який визначає методу доступу до активного об'єкта.
- Список поступаючих запитів від клієнтів.
- Планувальник, який вирішує, який запит виконати наступним.
- Реалізація методів активного об'єкта.
- Процедура зворотного виклику або змінна для отримання клієнтом результату.
Приклад шаблону активного об'єкта в Java . [4]
Далі наведено стандартний клас, який надає два методи, кожен з яких встановлює певне значення типу double для змінної val
. Цей клас НЕ відповідає шаблону активного об’єкта.
class MyClass {
private double val = 0.0;
void doSomething() {
val = 1.0;
}
void doSomethingElse() {
val = 2.0;
}
}
Клас є небезпечним у багатопоточному сценарії, оскільки обидва методи можуть бути викликані одночасно, тому значення val може бути невизначеним — це класична умова гонки. Можна використовувати синхронізацію для вирішення цієї проблеми, що в цьому тривіальному випадку легко. Але як тільки клас стає складним, синхронізація може стати дуже складною. [4]
Для того, щоб переписати цей клас саме як активний об’єкт, можна зробити наступне:
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) {
// ok, перервати диспетчер
}
}
}
).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;
}
}
);
}
}
- ↑ Douglas C. Schmidt; Michael Stal; Hans Rohnert; Frank Buschmann (2000). Pattern-Oriented Software Architecture, Volume 2: Patterns for Concurrent and Networked Objects. John Wiley & Sons. ISBN 0-471-60695-2.
- ↑ Bass, L., Clements, P., Kazman, R. Software Architecture in Practice. Addison Wesley, 2003
- ↑ Lavender, R. Greg; Schmidt, Douglas C. Active Object (PDF). Архів оригіналу (PDF) за 22 липня 2012. Процитовано 2 лютого 2007.
- ↑ а б Holub, Allen. Java Active Objects - A Proposal. Архів оригіналу за 22 червня 2013. Процитовано 16 червня 2014.