>
4.2. Голодування (starvation)
Проблема повній неприступності ресурсів певного потоку у зв'язку зі споживанням їх іншими потоками. Може проявляється при некоректному планування виконання (наприклад відмінність у пріоритетах на певних системах), або більш частий випадок - помилки при проектуванні та реалізації. Якщо у одного потоку буде виставлений дуже високий пріоритет, а в іншого низький, то перший може споживати істотну всі обчислювальні ресурси, в той час як другий не отримає їх зовсім. На щастя, така поведінка практично неможливо на більшості платформ підтримуваних Java. У той час як помилки при проектуванні та реалізації призводять до проблеми голодування цілком реальні. Наприклад помилка некоректної обробки умови виходу з циклу виконується при захопленої блокуванню, яку очікує інший потік.
Приклад 12.
public class Starvation {static void main (String [] args) {ReentrantLock lock1=new ReentrantLock (); t=new Thread (new Runnable () {
@ Overridevoid run () {();//реалізація аналогічна DeadLock.lock (); {
//критична секція.out.println ( completed );
} {. unlock ();
}
}
}, slave ) ;. start () ;. lock (); {(! Thread.currentThread (). isInterrupted ()) {
//умова виходу яке не наступає
}
} {. unlock ();
}. out.println ( finished );
}
}
Детектування проблеми голодування не настільки прямолінійно як у випадку з взаємним блокуванням. Якщо ситуація подібна наприклад, то можна легко вирахувати не очікується потік з нескінченним циклом будь утилітою отображающей стан процесів і потоків в операційній системі. Далі отримати дамп потоків і визначити місце виникнення проблеми. Але якщо в такій ситуації всередині циклу потік блокуватиметься в очікуванні події або просто віддавати рекомендацію планировщику (Thread.yield, Thread.sleep) поступитися поточний квант, то визначити її буде складніше. При подібних умовах можуть стати в нагоді як ручне спостереження за стеками виконання і станами потоків у часі, так і автоматичне профілювання додатки (може знадобитися тривалий час збору статистики).
4.3 Активна блокування (livelock)
Це зациклення алгоритму в результаті взаємодії станом, який в свою чергу може незалежно змінюватися ззовні. Умова існування змінюваного ззовні стану - паралелізм (необов'язково багатопоточність, наприклад, взаємодія процесів з файловою системою). При активній блокування потік не блокується, а продовжує спроби виконати корисну дію, але в результаті некоректної обробки помилки при його виконання повторює його знову. Наприклад завершення транзакції в СУБД, яка не може бути виконана через порушення в роботі сервера, але некоректний код трактує помилку як тимчасову і намагається повторити транзакцію. Ще один класичний приклад з області мережевих технологій. Якщо два або більше передавальних пристрої одночасно намагаються передати дані, то виявляючи колізію і повторюючи спроби передачі через рівні інтервали часу жоден пристрій не зможе нічого передати, тому що кожен раз розділюваний середу буде передавати сигнали декількох джерел.
Крім таких явних проблем блокуючих виконання, як згадані вище в цій секції, існують і менш критичні проблеми продуктивності та латентності (часу реакції). Напевно, найбільш поширеним їх видом, пов'язаним з продуктивністю, буде проблема зі слабко гранульованими блокуваннями (coarse-grained lock) або їх екстремальним варіантом - глобальними блокуваннями (global lock). Суть цієї проблеми зводиться до того, що в результаті великих розмірів критичної секції виконання на цій ділянці фактично серіалізуются (дивися 2.4 Блокування). До проблем латентності можна віднести ситуацію близьку до голодування, коли якийсь потік практично не отримує час центрального процесора або інший ресурс, в результаті чого розтягується час виконання операції.
У даному огляді описується, хоча б дуже стисло, більша частина основних питань пов'язаних з підтримкою паралелізму в Java. Сподіваюся, мені вдалося передати найбільш важливі аспекти цієї проблеми в достатньому для розуміння обсязі.
Для реалізації поставленої задачі я буду використовувати описані процеси і потоки, але мені немає необхідності використовувати описані в огляді методи, так як завдання стоїть в оцінці швидкодії обчисленні функції при використанні різної кількості потоків.
Алгоритм роботи програми
Згідно з цим алгоритмом напишемо текст програми. Лістинг програми наведемо нижче.
...