close

Вход

Забыли?

вход по аккаунту

?

10. Введение в Java. Основны многопоточного программирования. | Технострим

код для вставки
Введение в Java
Основы многопоточного
программирования
Нечаев Михаил
1
Основы многопоточного программирования на Java
Оглавление
-
Основные понятия
Потоки в Java
Закон Амдала
Критические секции
Пассивное ожидание
Неизменяемые объекты
Жизнеспособность
2
Основы многопоточного программирования на Java
-
Основные понятия
Потоки в Java
Закон Амдала
Критические секции
Пассивное ожидание
Неизменяемые объекты
Жизнеспособность
3
Основы многопоточного программирования на Java
Операционные системы
Типы
- Однозадачные
- Пакетные (batch-processing)
- Многозадачные / с разделением по времени (time-sharing)
- Кооперативная многозадачность (cooperative multitasking)
- Вытесняющая многозадачность (preemptive multitasking)
4
Основы многопоточного программирования на Java
Однозадачная система
Выполнение одной задачи в один момент времени
- Ждём завершения задачи
- Вся память у одной задачи
- Ресурсы ввода и вывода у одной задачи
- Часть ресурсов машины остаётся невостребованной
- Долгое время реагирования
5
Основы многопоточного программирования на Java
Пакетная система
Выполнение происходит пакетами
- Пакет — набор заданий от разный пользователей
- У каждой задачи своя память
- Текущая задача инициирует переключение на следующую
- Время исполнения задачи заранее неизвестно
- Управление заданиями осуществляется монитором
- Ресурсы ввода и вывода у одной задачи
- БОльшая загрузка ресурсов
- Долгое время реагирования
6
Основы многопоточного программирования на Java
Многозадачная система
Задачи соревнуются за использование процессора
- У каждой задачи своя память
- У каждой задачи ограниченное время исполнения
- Время исполнения задачи известно заранее
- Разделяемый ввод вывод
- Меньшее время отклика
7
Основы многопоточного программирования на Java
Кооперативная многозадачность
Каждая следующая задача выполняется после того, как
предыдущая сообщила об окончании.
Если в задаче возникла ошибка и нет вызова операции: «передать
исполнение другой задаче», — ломается вся система.
8
Основы многопоточного программирования на Java
Вытесняющая многозадачность
Существует планировщик процессов, который решает какой из
задач исполняться в текущий момент.
- Задача может быть переключена в процессе исполнения
- У задач есть приоритеты
- Быстрый отклик на пользовательские действия
9
Основы многопоточного программирования на Java
Основные понятия
Процесс — владеет память и ресурсами
Поток — контекст исполнения внутри процесса
- В процессе может быть несколько потоков
- Потоки внутри процесса работают с общей память этого процесса
10
Основы многопоточного программирования на Java
Модели программирования
- Однопоточное / однозадачное
- Ресурсы многоядерной системы используются если запущено
несколько независимых задач
- Многозадачное программирование
- Использование ресурсов многоядерной системы в рамках
одной задачи
- Общая память
- Передача сообщений
11
Основы многопоточного программирования на Java
Общая память
- Потоки выполняют операции над разделяемыми объектами
- Коммуникация между потоками: работа с общими объектами
Поток — 1
Поток — 2
Объект — 1
Объект — 2
Поток — 3
…
…
Объект — M
Поток — N
Общая память
12
Основы многопоточного программирования на Java
Передача сообщений
- Моделируем параллельную систему возможность передавать
потокам сообщения друг другу
- Применяется в распределённых системах
13
Основы многопоточного программирования на Java
Виды систем
- Параллельная система — несколько процессоров,
взаимодействующие друг с другом через общую память.
- Распределённая система — несколько процессоров
(компьютеров) соединённых в одну сеть.
- Взаимодействие через сообщения передаваемые по сети.
- У каждого процессора только своя локальная память
14
Основы многопоточного программирования на Java
Многопоточные программы
- Потоки соревнуются за процессор
- Общая память
- Потоки прерываются и переключаются
- Разделяемый ввод-вывод
- Возможность параллельного исполнения одной программы
- Взаимодействие между потоками:
- Синхронизация
- Обмен сообщениями
- Низкое время отклика
15
Основы многопоточного программирования на Java
Пример
Thread A:
0: x = 1
1: print x
2: exit
Thread B:
0: x = 2
1: print x
2: exit
A0,B0
x=0
(-.-)
A1,B0
x=1
(-.-)
A2,B0
x=1
(1.-)
A2,B1
A2,B2
x=2
(1.2)
A1,B1
x=2
(-.-)
A0,B1
x=2
(-.-)
A1,B1
x=1
(-.-)
A1,B2
A2,B1
A2,B2
x=2
(2.2)
16
A0,B2
x=2
(-.2)
A1,B2
A2,B1
A2,B2
x=1
(1.1)
17 возможных состояний
A1,B2
A2,B2
x=1
(2.1)
Основы многопоточного программирования на Java
Свойства параллельных программ
- Последовательные программы детерминированы
- Свойства программы на определённых входных параметрах
можно предопределить
- При отсутствии использовании «случайности»
- Параллельные программы не детерминированы
- Даже есть в каждом потоке детерминированная
последовательность операций
- Процесс работы нельзя предопределить
- Фактическое исполнение может варьироваться
17
Основы многопоточного программирования на Java
-
Основные понятия
Потоки в Java
Закон Амдала
Критические секции
Пассивное ожидание
Неизменяемые объекты
Жизнеспособность
18
Основы многопоточного программирования на Java
Процессы и потоки
- Процесс (Process)
- Находится в изолированной среде выполнения
- Имеет собственное пространство памяти
- Процесс != программа или приложение
- Приложение может быть набором взаимодействующих
процессов
- В каждом процессе как минимум один поток
- Поток (Thread)
- Облегчённый процесс (+ легче создавать)
- Использует ресурсы и память процесса
- Программа запускается в главном потоке
19
Основы многопоточного программирования на Java
Поток
- Каждый поток в Java связан с объектом класса Thread
- Два пути создания многопоточного приложения
- Явный контроль над потоками
- Создать поток каждый раз при необходимости
асинхронного исполнения
- Неявный контроль над потоками
- Передача управления менеджеру потоков
- Отдавать менеджеру задачи на исполнение
20
Основы многопоточного программирования на Java
Создание потока
1. new Thread(Runnable target)
или
@FunctionalInterface
public interface Runnable
2. extend Thread
/**
}
{
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p>
* The general contract of the method <code>run</code> is that it may
* take any action whatsoever.
*
* @see
java.lang.Thread#run()
*/
public abstract void run();
21
Основы многопоточного программирования на Java
22
Создание потока
Какой вариант лучше?
public class ImplementRunnable implements Runnable {
@Override
public void run() {
System.out.println("Created");
}
}
public static void main(String[] args) {
new Thread(new ImplementRunnable()).start();
}
public class ExtendThread extends Thread {
@Override
public void run() {
System.out.println("Created");
}
}
public static void main(String[] args) {
new ExtendThread().start();
}
Основы многопоточного программирования на Java
Состояния потока
- New: Создали, но не запустили — isAlive = false
- Thread thread = new Thread(…)
- Runnable: Запущен
- thread.start()
- Blocked: Заблокирован ожидая получения монитора
- Waiting: Ждёт начала исполнения или пробуждения
- Object.wait()
- thread.join();
- TimedWaiting: Аналогично предыдущему, но с таймером
- Terminated: Завершён — isAlive = false
Вызов: Thread.getState(); Возвращает объект: enum Thread.State
23
Основы многопоточного программирования на Java
Приостановка потока
public class ThreadSleep {
public static void main(String[] args) throws InterruptedException {
System.out.println(System.currentTimeMillis());
Thread.sleep(2000); //2s in millis
System.out.println(System.currentTimeMillis());
Thread.sleep(2000, 999_999); //2s+ in millis + nanos
System.out.println(System.currentTimeMillis());
}
}
—
1490575412694
1490575414696
1490575416699
24
Основы многопоточного программирования на Java
Прерывание потока
- С помощью прерывания (interrupt) можно сообщить потоку что
нужно остановиться
- Разработчик сам определяет поведение после прерывания
- Для корректной работы нужно поддержать данную
функциональность
25
jPoint 2017
26
/**
”одинаковые”
1. Такие же по состоянию внутренней структуры.
2. Не про контракт “equals и hashcode”.
3. Не имеет отношение к проверке референсов.
*/
Java Puzzlers. jPoint 2017 (пример начинается с 10:50)
jPoint 2017
27
List[] twins = new List[2];
Arrays.setAll(twins, ArrayList::new);
/**
A. Одинаковые пустые списки
B. Одинаковые не пустые списки
C. Не одинаковые пустые списки
D. Не одинаковые не пустые списки
*/
jPoint 2017
28
List[] twins = new List[2];
Arrays.setAll(twins, ArrayList::new);
/**
A. Одинаковые пустые списки
B. Одинаковые не пустые списки
[C]. Не одинаковые пустые списки
D. Не одинаковые не пустые списки
*/
jPoint 2017
29
public static <T> void setAll(T[] array, IntFunction<? extends T> generator) {
Objects.requireNonNull(generator);
for (int i = 0; i < array.length; i++)
array[i] = generator.apply(i);
}
@FunctionalInterface
public interface IntFunction<R> {
}
/**
* Applies this function to the given argument.
*
* @param value the function argument
* @return the function result
*/
R apply(int value);
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
Основы многопоточного программирования на Java
Ожидание потока
- С помощью ожидания (join) можно дождаться исполнения другого
потока
- Можно указать время ожидания (почти реальное - зависит от ОС)
- Аналогично sleep нужно поддержать interrupt
30
Основы многопоточного программирования на Java
Свойства потока
Thread thread = new Thread(() -> {});
thread.setName("name");
thread.setDaemon(true);
thread.setPriority(7);
//После start свойства изменить нельзя
thread.start();
System.out.println(thread.isAlive()); //boolean
System.out.println(thread.isInterrupted()); //boolean
System.out.println(thread.isDaemon()); //boolean
System.out.println(thread.getName()); //String
System.out.println(thread.getId()); //long
//MIN_PRIORITY = 1
//NORM_PRIORITY = 5
//MAX_PRIORITY = 10
System.out.println(thread.getPriority()); //int
//NEW,RUNNABLE,BLOCKED,WAITING,TIMED_WAITING,TERMINATED
System.out.println(thread.getState()); //State
31
Основы многопоточного программирования на Java
-
Основные понятия
Потоки в Java
Закон Амдала
Критические секции
Пассивное ожидание
Неизменяемые объекты
Жизнеспособность
32
Основы многопоточного программирования на Java
33
Основы многопоточного программирования на Java
-
Основные понятия
Потоки в Java
Закон Амдала
Критические секции
Пассивное ожидание
Неизменяемые объекты
Жизнеспособность
34
Основы многопоточного программирования на Java
Пример
Клиент хочет снять со счёта сто рублей
Банк
- Убедиться что на счету клиента есть сто рублей
- Снять сто рублей со счёта клиента
35
Основы многопоточного программирования на Java
Пример
Первый клиент (К1) хочет снять со счёта сто рублей
Второй клиент (К2) хочет снять с этого же счёта сто рублей
Банк
- К1: Убедиться что на счету есть сто рублей
- К1: Снять сто рублей со счёта
- К2: Убедиться что на счету есть сто рублей
- К2: Отказать в снятии денег
36
Основы многопоточного программирования на Java
Пример
Первый клиент (К1) хочет снять со счёта сто рублей
Второй клиент (К2) хочет снять с этого же счёта сто рублей
Банк
- К1: Убедиться что на счету есть сто рублей
- К2: Убедиться что на счету есть сто рублей
- К1: Снять сто рублей со счёта
- К2: Снять сто рублей со счёта
На счету банка -100 рублей :(
37
Основы многопоточного программирования на Java
Проблема
- При создании многопоточных программ возникает ситуация, в
которой нескольким процессам требуется одновременно
получить доступ к некоторым ресурсам
- Процессы хотят либо одновременно записать данные в память,
либо один из них хочет прочитать, а другой записать в одно и
тоже время
38
Основы многопоточного программирования на Java
Решение
Самый простой способ решения задачи взаимного исключения —
критическая секция (critical section)
- Запрещение прерываний при выполнении важных частей
программы
39
Основы многопоточного программирования на Java
Задача взаимного исключения
Требуется согласовать работу n > 1 параллельных процессов при
использование какого-либо критического ресурса таким образом,
чтобы удовлетворялись следующие свойства: …
Solution of a Problem in Concurrent Programming Control
40
Основы многопоточного программирования на Java
Задача взаимного исключения. Свойства
- 1. Внутри критической секции в одно и тоже время только один
поток
- 2. КС не должны иметь приоритеты относительно друг друга
- 3. Остановка процесса вне КС не должно влиять на дальнейшую
работу процессов по использованию общего ресурса
41
Основы многопоточного программирования на Java
Задача взаимного исключения. Свойства
- 4. Решение о попадании в КС при одинаковом времени
поступления запросов на вход и равноприоритетности процессов
конечно
- 5. Относительные скорости развития событий неизвестны и
произвольны
42
Основы многопоточного программирования на Java
Задача взаимного исключения. Свойства
- 6. Вне КС процесс может менять состояние на любое отличное от
активного
- 7. Процесс внутри КС, должен освободить её самостоятельно за
конечное время
43
Основы многопоточного программирования на Java
Блокировки
Любой последовательный объект можно сделать параллельным,
линеаризуемым.
Грубая блокировка: блокируем всю операцию целиком
Тонкая блокировка: блокируем только операции над общими
объектами внутри метода (не весь вызов метода)
44
Основы многопоточного программирования на Java
Блокировки
public class Counter {
private int c = 0;
public void increment() {
c++;
}
public void decrement() {
c--;
}
public int value() {
return c;
}
}
increment:
1. Получить значение <c>
2. Увеличить полученное значение
3. Записать новое значение в <c>
45
Основы многопоточного программирования на Java
Блокировки
public class Counter {
private int c = 0;
public void increment() {
c++;
}
public void decrement() {
c--;
}
public int value() {
return c;
}
}
increment:
1. Получить значение <c>
2. Увеличить полученное значение
3. Записать новое значение в <c>
Один из возможных вариантов
A1: 0 = c
B1: 0 = c
A2: 0 - 1 = -1
B2: 0 + 1 = +1
A3: c = -1
B3: c = 1
46
Основы многопоточного программирования на Java
Ошибки согласованности памяти
Чтобы избежать данную проблему, необходимо понимать работу
отношения «Произошло до» (happens-before)
A: int counter = 0;
B: int counter = 0;
A: counter++;
B: System.out.println(counter); // 0 или 1?
Memory Consistency Properties
Happens-before Order
47
Основы многопоточного программирования на Java
happens-before
1. synchronized методы
2. synchronized операторы
3. Запись/чтение volatile полей
4. Thread.start()
5. Thread.join()
6. …
48
Основы многопоточного программирования на Java
Synchronized методы
В такой метод потоки могут заходить только по отдельности.
После завершения метода устанавливается связь happens-before.
Нельзя синхронизировать конструктор класса.
49
Основы многопоточного программирования на Java
Конструкторы
class Clazz {
public Clazz() {
instances.add(this);
}
}
private List<Clazz> instances = new ArrayList<>();
Плохо!
Другие потоки могут увидеть ссылку на объект до завершения
создания объекта
50
Основы многопоточного программирования на Java
Внутренние блокировки и синхронизация
public class SynchronizedStatements {
private int c = 0;
public class SynchronizedCounter {
public void increment() {
synchronized (this) {
c++;
}
}
private int c = 0;
public synchronized void increment() {
c++;
}
public void decrement() {
synchronized (this) {
c--;
}
}
public synchronized void decrement() {
c--;
}
public synchronized int value() {
return c;
}
public int value() {
synchronized (this) {
return c;
}
}
}
}
51
Основы многопоточного программирования на Java
Synchronized методы
Стратегия использования для предотвращения ошибок
- Если объект виден более чем в одном потоке
- Все чтения и записи его переменных нужно производить
внутри synchronized методов
- Если у объекта есть final переменные
- Их можно читать напрямую, так как они неизменяемые после
создания
52
Основы многопоточного программирования на Java
Тонкая блокировка
public class FineGrainedSynchronization {
private
private
private
private
int a
int b
final
final
= 0;
= 0;
Object lockA = new Object();
Object lockB = new Object();
public void incrementA() {
synchronized (lockA) {
a++;
}
}
public void incrementB() {
synchronized (lockB) {
b--;
}
}
}
53
Основы многопоточного программирования на Java
Повторная синхронизация
Если поток взял блокировку на каком-то объекте, то он имеет
право брать её и дальше до момента отпускания всех мониторов
class Reentrant {
данного объекта.
private void run() {
new Thread(() -> new Reentrant().a()).start();
}
—
A-1
B-1
C
B-2
A-2
synchronized void a() {
System.out.println("A-1");
b();
System.out.println("A-2");
}
synchronized void b() {
System.out.println("B-1");
c();
System.out.println("B-2");
}
}
synchronized void c() {
System.out.println("C");
}
54
Основы многопоточного программирования на Java
Атомарный доступ
Атомарная операция — выполняемая за раз.
Либо происходит полностью, либо вообще не происходит.
Значение всегда читается из общей памяти.
Значение всегда записывается в общую память.
55
Основы многопоточного программирования на Java
Атомарный доступ
Атомарный операции:
- Чтение и запись ссылочных переменных и примитивных типов
- Кроме long и double
- Чтение и запись переменных помеченных как volatile
public class VolatileVariables {
private volatile long x;
private volatile double y;
}
56
Основы многопоточного программирования на Java
-
Основные понятия
Потоки в Java
Закон Амдала
Критические секции
Пассивное ожидание
Неизменяемые объекты
Жизнеспособность
57
Основы многопоточного программирования на Java
Активное ожидание
class QueueActive {
private String data;
- Вечный цикл — расточительно
String getData() {
while (true) {
synchronized (this) {
if (this.data != null) {
String result = this.data;
this.data = null;
return result;
}
}
}
}
}
void setData(String data) {
while (true) {
synchronized (this) {
if (this.data == null) {
this.data = data;
break;
}
}
}
}
58
Основы многопоточного программирования на Java
Пассивное ожидание
- У каждого объекта есть встроенный монитор
- И множество ожидающих тредов (wait set)
- wait()
- Тред освобождает блокировку
- Добавляется в wait set
- Приостанавливает выполнение
- notify(All)
- Тред выходит из synchronized блока
- Сообщает другому (другим) из wait set что нужно проснуться
- Выполнение которого продолжится после команды wait
59
Основы многопоточного программирования на Java
Пассивное ожидание
- Все вызовы wait должны быть внутри цикла
- При вызове wait/notify тред должен владеть блокировкой
- Также тред будит команда interrupt
60
Основы многопоточного программирования на Java
Пассивное ожидание
- Менеджмент через wait/notify
class QueuePassive {
private String data;
synchronized String getData() throws InterruptedException {
while (this.data == null) {
wait();
}
String result = this.data;
this.data = null;
notifyAll(); //notify() if one thread
return result;
}
}
synchronized void setData(String data) throws InterruptedException {
while (this.data != null) {
wait();
}
this.data = data;
notifyAll(); //notify() if one thread
}
61
Основы многопоточного программирования на Java
QueuePassive queue = new QueuePassive();
AtomicInteger count = new AtomicInteger(0);
int maxSetters = 2;
int maxGetters = 2;
Thread[] setters = new Thread[maxSetters];
Thread[] getters = new Thread[maxGetters];
for (int i = 0; i < maxSetters; i++) {
final int left = 10 * i;
final int right = 10 + left;
setters[i] = new Thread(() -> {
String threadName = Thread.currentThread().getName();
System.out.println("Setter " + threadName);
int current = left;
while (current < right) {
try {
String data = threadName + " : " + current;
queue.setData(data);
current++;
} catch (InterruptedException e) {
System.out.println("Interrupted in set " + threadName);
}
}
});
}
for (int i = 0; i < maxGetters; i++) {
getters[i] = new Thread(() -> {
String threadName = Thread.currentThread().getName();
System.out.println("Getter " + threadName);
try {
while (true) {
String data = threadName + " -- " + queue.getData();
System.out.println(data);
count.incrementAndGet();
}
} catch (InterruptedException e) {
System.out.println("Interrupted in get " + threadName);
}
});
}
Arrays.stream(setters).forEach(Thread::start);
Arrays.stream(getters).forEach(Thread::start);
Arrays.stream(setters).forEach((t) -> {
try {
t.join();
} catch (InterruptedException ie) {
System.out.println("Interrupted in join "
+ Thread.currentThread().getName());
}
});
Arrays.stream(getters).forEach(Thread::interrupt);
System.out.println(count.get() + " == " + 10 * maxSetters);
—
Setter Thread-0
Setter Thread-1
Getter Thread-2
Thread-2 -- Thread-0 : 0
Thread-2 -- Thread-1 : 10
Getter Thread-3
Thread-2 -- Thread-0 : 1
Thread-3 -- Thread-1 : 11
Thread-2 -- Thread-0 : 2
Thread-3 -- Thread-1 : 12
Thread-2 -- Thread-0 : 3
Thread-3 -- Thread-1 : 13
Thread-2 -- Thread-0 : 4
Thread-3 -- Thread-1 : 14
Thread-3 -- Thread-1 : 15
Thread-3 -- Thread-1 : 16
Thread-2 -- Thread-0 : 5
Thread-2 -- Thread-0 : 7
Thread-2 -- Thread-1 : 17
Thread-3 -- Thread-0 : 6
Thread-3 -- Thread-1 : 19
Thread-2 -- Thread-1 : 18
Thread-3 -- Thread-0 : 8
Thread-2 -- Thread-0 : 9
20 == 20
Interrupted in get Thread-2 Interrupted in get Thread-3
62
Основы многопоточного программирования на Java
Оглавление
-
Основные понятия
Потоки в Java
Закон Амдала
Критические секции
Пассивное ожидание
Неизменяемые объекты
Жизнеспособность
63
Основы многопоточного программирования на Java
Пример
public class RagInterval {
private String name;
private int left;
private int right;
public RagInterval(String name, int left, int right) {
this.name = name;
this.left = left;
this.right = right;
}
public synchronized void update(String name, int left, int right) {
this.name = name;
this.left = left;
this.right = right;
}
public synchronized String getName() {
return name;
}
}
public synchronized boolean inside(int coordinate) {
return left <= coordinate && coordinate <= right;
}
64
Основы многопоточного программирования на Java
Проблема
RagInterval ragInterval = new RagInterval("First", 1, 2);
//Thread 1
String name = ragInterval.getName();
//Thread 2
ragInterval.update("Second", 1, 10);
boolean inside = ragInterval.inside(5); // ???
65
Основы многопоточного программирования на Java
Неизменяемые объекты
- Без set методов
- Все поля final и private
- Без наследников
- final class
- приватный конструктор + фабричный метод
- Если в полях экземпляра ссылки на изменяемые объекты
- Не изменяйте значения в этих объектах
- Не храните ссылки переданные в конструктор
- При необходимости делайте копии объектов
66
Основы многопоточного программирования на Java
Неизменяемые объекты
final public class StrongInterval {
private final String name;
private final int left;
private final int right;
public StrongInterval(String name, int left, int right) {
this.name = name;
this.left = left;
this.right = right;
}
public String getName() {
return name; //String is immutable
}
public boolean inside(int coordinate) {
return left <= coordinate && coordinate <= right;
}
}
67
Основы многопоточного программирования на Java
Неизменяемые объекты
class Singleton {
private static Singleton instance = null;
private Singleton() {
/* empty */
}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
68
Основы многопоточного программирования на Java
-
Основные понятия
Потоки в Java
Закон Амдала
Критические секции
Пассивное ожидание
Неизменяемые объекты
Жизнеспособность
69
Основы многопоточного программирования на Java
Проблемы жизнеспособности
- Deadlock — Тупик
- Starvation — Голод
- Livelock — Динамическая взаимоблокировка
70
Основы многопоточного программирования на Java
Deadlock
Deadlock — два или более потока заблокированы навсегда,
ожидая друг друга.
Thread1:
1: mutexA.lock
2: mutexB.lock
A
…
3: mutexB.unlock
4: mutexA.unlock
B
B
A
Thread2:
1: mutexB.lock
2: mutexA.lock
…
3: mutexA.unlock
4: mutexB.unlock
71
Основы многопоточного программирования на Java
Deadlock
Deadlock — два или более потока заблокированы навсегда,
ожидая друг друга.
Решение: глобально иерархически упорядочить все блокировки
Thread1:
A
1: mutexA.lock
2: mutexB.lock
…
3: mutexB.unlock
4: mutexA.unlock
B
Thread2:
1: mutexA.lock
2: mutexB.lock
…
3: mutexB.unlock
4: mutexA.unlock
72
Основы многопоточного программирования на Java
Проблемы взаимного исключения
- Условные условия прогресса
- Инверсия приоритетов
- Последовательное исполнение операций
73
Основы многопоточного программирования на Java
Полезные ссылки
Шипилёв. Java Memory Model Pragmatics
https://shipilev.net/#jmm
Java Spec. Chapter 17. Threads and Locks
https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html
Java Concurrency Tutorial
https://docs.oracle.com/javase/tutorial/essential/concurrency/index.html
Слайды Георгия Корнеева
http://www.kgeorgiy.info/courses/java-advanced/slides/threads-1.xhtml
Визуалиции
http://sourceforge.net/projects/javaconcurrenta/
Примеры с лекции
https://github.com/nms403/java_samples/tree/master/src/ru/sample/
concurrency/low
74
75
Спасибо за внимание!
https://tt.me/mikhailnechaev
https://tt.me/java_open_2019
Автор
tekhnostrim
Документ
Категория
Без категории
Просмотров
36
Размер файла
1 837 Кб
Теги
Введение в Java.
1/--страниц
Пожаловаться на содержимое документа