Активний об'єкт (англ. 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;
}
}
);
}
}