№ | Слайд | Текст |
1 |
 |
Многопоточное программированиеJava Advanced |
2 |
 |
Краткое содержаниеВведение Классические задачи многопоточного программирования Атомарные операции Примитивы синхронизации Решения задач многопоточного программирования Заключение |
3 |
 |
ВведениеЧасть 1 |
4 |
 |
Многопоточное программированиеПрограмма одновременно имеет несколько потоков исполнения Потоки должны взаимодействовать (синхронизироваться) друг с другом |
5 |
 |
ПримерУмножение матриц. // Матрицы размера n на n double[][] a, b, c; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { c[i][j] = 0; for (int k = 0; k < n; k++) { c[i][j] += a[i][k] * b[k][j]; } } } |
6 |
 |
ПримерИтеративный параллелизм. // Матрицы размера n на n double[][] a, b, c; for (int i = 0; i < n; i++) { // Параллельно for (int j = 0; j < n; j++) { // Параллельно c[i][j] = 0; for (int k = 0; k < n; k++) { c[i][j] += a[i][k] * b[k][j]; } } } |
7 |
 |
ПримерОбмен сообщениями (1). Рабочий поток Worker[i] { double[] a; // a[i][*] double[][] b; // b[*][*] double[] c; // c[i][*] receive a, b from coordinator; for (int j = 0; j < n; j++) { c[j] = 0; for (int k = 0; k < n; k++) { c[j] += a[k] * b[k][j]; } } send c to coordinator; } |
8 |
 |
ПримерОбмен сообщениями (2). Управляющий поток coordinator(int i) { double[][] a, b, c; for (int i = 0; i < n; i++) { send a[i], b to worker[i]; } for (int i = 0; i < n; i++) { receive c[i] from worker[i]; } } |
9 |
 |
ПримерОбмен сообщениями (3). worker[i] { double[] a; // a[i][*] double[] b; // b[*][i] double[] c; // a[i][*] receive a, b from coordinator; for (int j = 0; j < n; j++) { double s = 0; for (int k = 0; k < n; k++) { s += a[k] * b[k]; } c[(i + j) % n] = s; send b to worker[(i + 1) % n]; receive b from worker[(i + n - 1) % n]; } send c to coordinator; } |
10 |
 |
ПримерВычисление интеграла. Адаптивное вычисление интеграла f(x) double integrate(double l, double r) { if (abs(area(l, m) + area(m, r) - area(l, r)) > EPS) { return integrate(l, m) + integrate(m, r); } else { return area(l, m) + area(m, r); } } double area(double l, double r) { return (f(l) + f(r)) * (r - l) / 2; } |
11 |
 |
ПримерРекурсивный параллелизм. Адаптивное вычисление интеграла f(x) double integrate(double l, double r) { double m = (l + r) / 2; double la = area(l, m); double ra = aread(m, r); if (abs(la + ra - area(l, r)) > EPS) { la = integrate(l, m); // Параллельно ra = integrate(m, r); // Параллельно } return la + ra; } |
12 |
 |
Основные операцииСоздание потока Уничтожение потока Неделимая операция ?statements? Неделимая операция с ожиданием условия ?await(C) statements? |
13 |
 |
ПримерПоиск максимума (1). Без синхронизации int max = 0; create worker[i] { if (max < a[i]) max = a[i]; } С синхронизацией int max = 0; create worker[i] { ?if (max < a[i]) max = a[i];? } |
14 |
 |
ПримерПоиск максимума (2). Протокол Проверить-Проверить-Установить int max = 0; create worker[i] { if (max < a[i]) { ? if (max < a[i]) max = a[i]; ? } } |
15 |
 |
Свойства планированияСправедливость Безусловная Слабая Сильная Безопасность Живучесть |
16 |
 |
Классические задачи многопоточного программированияЧасть 2 |
17 |
 |
Задача доступа к общему ресурсуНесколько потоков обращаются к общему ресурсу |
18 |
 |
Производитель-потребительОдин поток производит данные, второй их потребляет Несколько потоков производят данные и несколько их потребляют Данные могут храниться в очереди |
19 |
 |
Задача о читателях и писателяхЧитать могут много потоков одновременно Писать может только один поток Читать во время записи нельзя |
20 |
 |
Задача об обедающих философах5 Философов, 5 тарелок, 5 вилок Философ Думает Ест Что бы есть нужны обе вилки |
21 |
 |
Задания-работникиПоток-клиент ждет выполнения задания потоком-сервером |
22 |
 |
Атомарные операцииЧасть 3 |
23 |
 |
Атомарная операцияОперация выполняемая как единое целое Чтение Запись Неатомарные операции Инкремент Декремент |
24 |
 |
Виды атомарных операцийОперация чтения get Операция записи set Операции записи и чтения addAndGet, incAndGet, … getAndAdd, getAndInc, … Операция условной записи compareAndSet |
25 |
 |
Решение задачи доступа к ресурсу// Получение доступа к ресурсу while(!v.compareAndSet(0, 1)); // Действия с ресурсом // Освобождение ресурса v.set(0); |
26 |
 |
Примитивы синхронизацииЧасть 4 |
27 |
 |
Критическая секцияТолько один поток может выполнять действия в критической секции Именованные критические секции < name: statements > |
28 |
 |
Решение задачи доступа к ресурсуДоступ производится в критической секции resource < resource: // Доступ к ресурсу > |
29 |
 |
Реализации критических секцийНа основе блокировки ? await(!lock) lock = true; ? // Вход // Критическая секция lock = false; // Выход На основе атомарных операций while(!lock.compareAndSet(0, 1)); // Вход // Критическая секция lock.set(0); // Выход |
30 |
 |
Блокировка (lock, mutex)Только один поток может владеть блокировкой Могут быть использованы для передачи событий Операции lock получить блокировку unlock отдать блокировку tryLock попробовать получить блокировку |
31 |
 |
Решение задачи доступа к ресурсуДоступ ограничен блокировкой lock // Получение блокировки lock.lock(); // Доступ к ресурсу // Освобождение блокировки lock.unlock() |
32 |
 |
СемафорХранит количество разрешений на вход Могут быть использованы для передачи событий Операции acquire получить разрешение release добавить разрешение tryAcquire попробовать получить разрешение |
33 |
 |
БарьерПотоки блокируются пока все потоки не прибудут к барьеру Одноразовый Многоразовый Операции arrive прибытие к барьеру |
34 |
 |
МониторРазделяемые переменные инкапсулированы в мониторе Код в мониторе исполняется не более чем одним потоком Условия Операции с условиями wait ожидание условия notify сообщение об условии одному потоку notifyAll сообщение об условии всем потокам |
35 |
 |
Решение классических задач параллельного программированияЧасть 5 |
36 |
 |
Производитель-потребительРешение с помощью разделенных блокировок Производитель empty.lock(); // копирование full.unlock(); Потребитель full.lock(); // копирование empty.unlock(); |
37 |
 |
Задания-работникиРешение с помощью монитора Задание queue.add(task); queue.notify(); task.wait(); Работник while (queue.isEmpty()) queue.wait(); Task t = queue.get(); // Обработка задания t.notify(); |
38 |
 |
Задача об обедающих философахРешение с помощью асимметрии Все философы кроме одного берут сначала левую, затем правую вилку Оставшийся философ берет сначала правую, затем левую вилку |
39 |
 |
Задача о читателях и писателях (1)Решение с помощью блокировки Читатель ? if (nr++ == 0) busy.lock(); ? // Чтение ? if (--nr == 0) busy.unlock(); ? Писатель busy.lock(); // Запись busy.unlock(); |
40 |
 |
Задача о читателях и писателях (2)Решение с помощью передачи эстафеты Особенности решения Если есть и писатели и читатели, то вход закрывается Пока есть читатели – разрешать чтение Когда нет читателей – разрешить запись Когда нет ни читателей ни писателей – открыть вход |
41 |
 |
Задача о читателях и писателях (3) |
42 |
 |
Задача о читателях и писателяхПередача эстафеты if (nw == 0 && dr > 0) { dr--; r.unlock(); // Возобновить процесс-читатель else if (nr == 0 && nw == 0 && dw > 0) { dw--; w.unlock(); // Возобновить процесс-писатель } else { e.unlock(); // Открыть вход } |
43 |
 |
Задача о читателях и писателяхЧитатель e.lock(); if (nw > 0) { dr++; e.unlock(); r.lock(); } // Доступ разрешен nr++; // Передача эстафеты // Чтение e.lock(); nr--; // Передача эстафеты |
44 |
 |
Задача о читателях и писателяхПисатель e.lock(); if (nw > 0 || nr > 0) { dw++; e.unlock(); w.lock(); } nw++; // Передача эстафеты // Запись e.lock(); nw--; // Передача эстафеты |
45 |
 |
ЗаключениеЧасть 6 |
46 |
 |
СсылкиЭндрюс Г. Основы многопоточного, параллельного и распределенного программирования Lea D. Concurrent Programming in Java |
47 |
 |
Вопросы |
«Операция в программировании» |
http://900igr.net/prezentatsii/informatika/Operatsija-v-programmirovanii/Operatsija-v-programmirovanii.html