3.1 Активен обект
Активният обект е модел на проектиране, който разделя нишката за изпълнение на метод от нишката, в която е бил извикан. Целта на този модел е да осигури паралелно изпълнение чрез извикване на асинхронни методи и планировчик за обработка на заявки.
Опростена version:
Класически вариант:
Този шаблон има шест елемента:
- Прокси обект, който предоставя интерфейс към публичните методи на клиента.
- Интерфейс, който дефинира методи за достъп за активния обект.
- Списък на входящи заявки от клиенти.
- Планировчик, който определя реда, в който да се изпълняват заявките.
- Внедряване на методи на активен обект.
- Процедура за обратно извикване or променлива за клиента, за да получи резултат.
3.2 заключване
Моделът за заключване е механизъм за синхронизиране, който позволява изключителен достъп до споделен ресурс между множество нишки. Заключванията са един от начините за налагане на политика за контрол на едновременността.
По принцип се използва меко заключване, като се допуска, че всяка нишка се опитва да „приеме заключването“, преди да получи достъп до съответния споделен ресурс.
Въпреки това, някои системи предоставят задължителен механизъм за заключване, чрез който опит за неоторизиран достъп до заключен ресурс ще бъде прекратен чрез хвърляне на изключение на нишката, която се е опитала да получи достъп.
Семафорът е най-простият тип ключалка. По отношение на достъпа до данни не се прави разлика между режимите на достъп: споделен (само за четене) or изключителен (четене-запис). В споделен режим множество нишки могат да поискат заключване за достъп до данни в режим само за четене. Изключителният режим на достъп се използва и в алгоритмите за актуализиране и изтриване.
Видовете ключалки се отличават със стратегията за блокиране на продължаването на изпълнението на нишката. В повечето реализации искането за заключване не позволява нишката да продължи да се изпълнява, докато заключеният ресурс не е наличен.
Spinlock е заключване, което чака в цикъл, докато не бъде предоставен достъп. Такова заключване е много ефективно, ако нишката чака за заключване за малко време, като по този начин се избягва прекомерното разсрочване на нишките. Разходите за изчакване за достъп ще бъдат значителни, ако една от нишките задържи заключването за дълго време.
За ефективно внедряване на заключващия механизъм е необходима поддръжка на хардуерно ниво. Поддръжката на хардуера може да бъде реализирана като една or повече атомарни операции като "тест-и-задаване", "извличане-и-добавяне" or "сравняване-и-размяна". Такива инструкции ви позволяват да проверите без прекъсване дали ключалката е свободна и ако е така, тогава придобийте ключалката.
3.3 Монитор
Моделът Monitor е механизъм за взаимодействие и синхронизиране на процеса на високо ниво, който осигурява достъп до споделени ресурси. Подход за синхронизиране на две or повече компютърни задачи с помощта на общ ресурс, обикновено хардуер or набор от променливи.
При многозадачност, базирана на монитор, компилаторът or интерпретаторът прозрачно вмъква code за заключване-отключване в подходящо форматирани рутинни proceduresи, прозрачно за програмиста, спестявайки на програмиста изрично извикване на примитиви за синхронизиране.
Мониторът се състои от:
- набор от proceduresи, които взаимодействат със споделен ресурс
- мютекс
- променливи, свързани с този ресурс
- инвариант, който дефинира условия за избягване на състояние на състезание
Процедурата за наблюдение придобива mutex преди започване на работа и го задържа or докато proceduresата излезе, or докато се изчака определено condition. Ако всяка proceduresа гарантира, че инвариантът е верен преди освобождаването на мютекса, тогава никоя задача не може да придобие ресурса в състояние на състезание.
Ето How синхронизираният оператор работи в Java с методите wait()
и notify()
.
3.4 Заключване с двойна проверка
Двойно провереното заключване е модел на паралелен дизайн, предназначен да намали режийните разходи за получаване на заключване.
Първо, conditionто за блокиране се проверява без ниHowва синхронизация. Нишката се опитва да получи заключване само ако резултатът от проверката показва, че трябва да получи заключване.
//Double-Checked Locking
public final class Singleton {
private static Singleton instance; //Don't forget volatile modifier
public static Singleton getInstance() {
if (instance == null) { //Read
synchronized (Singleton.class) { //
if (instance == null) { //Read Write
instance = new Singleton(); //
}
}
}
}
Как да създадете единичен обект в среда, безопасна за нишки?
public static Singleton getInstance() {
if (instance == null)
instance = new Singleton();
}
Ако създадете Singleton обект от различни нишки, тогава може да има ситуация, при която няколко обекта се създават едновременно и това е неприемливо. Следователно е разумно създаването на обекта да бъде обвито в синхронизиран оператор.
public static Singleton getInstance() {
synchronized (Singleton.class) {
if (instance == null)
instance = new Singleton();
}
}
Този подход ще работи, но има малък недостатък. След като обектът бъде създаден, всеки път, когато се опитате да го получите в бъдеще, ще се извършва проверка в синхронизирания блок, което означава, че текущата нишка и всичко, свързано с нея, ще бъдат заключени. Така че този code може да бъде малко оптимизиран:
public static Singleton getInstance() {
if (instance != null)
return instance;
synchronized (Singleton.class) {
if (instance == null)
instance = new Singleton();
}
}
На някои езици и/or на някои машини не е възможно безопасно да се приложи този модел. Поради това понякога се нарича анти-модел. Такива характеристики доведоха до появата на стриктната връзка на реда „случва се преди“ в модела на паметта на Java и модела на паметта на C++.
Обикновено се използва за намаляване на режийните разходи за внедряване на мързелива инициализация в многонишкови програми, като модела за проектиране на Singleton. При ленива инициализация на променлива, инициализацията се отлага, докато стойността на променливата е необходима при изчислението.
3.5 График
Scheduler е модел на паралелен дизайн, който предоставя механизъм за прилагане на политика за планиране, но е независим от всяка конкретна политика. Управлява реда, в който нишките трябва да изпълняват последователен code, използвайки обект, който изрично указва последователността от чакащи нишки.
GO TO FULL VERSION