1. Многопоточность в Java: основы
Алексей Владыкин
17 ноября 2014
Алексей Владыкин Многопоточность (1) 17 ноября 2014 1 / 24
2. 1 Общие сведения о параллелизме
2 Управление потоками
3 Синхронизация потоков
4 Модель памяти
Алексей Владыкин Многопоточность (1) 17 ноября 2014 2 / 24
3. Общие сведения о параллелизме
Алексей Владыкин Многопоточность (1) 17 ноября 2014 3 / 24
4. Общие сведения о параллелизме
Мотивация
Одновременное выполнение нескольких действий
(например, отрисовка пользовательского интерфейса и передача
файлов по сети)
Ускорение вычислений
(при наличии нескольких вычислительных ядер)
Алексей Владыкин Многопоточность (1) 17 ноября 2014 4 / 24
5. Общие сведения о параллелизме
Закон Амдала
S(N) =
1
(1 − P) + P
N
S — ускорение (speedup)
P — доля вычислений, которые возможно распараллелить
N — количество вычислительных ядер
Алексей Владыкин Многопоточность (1) 17 ноября 2014 5 / 24
6. Общие сведения о параллелизме
Параллелизм в Java
Запуск нескольких JVM на одном или на разных компьютерах
Нет общей памяти
Взаимодействие через файловую систему или сетевое соединение
Алексей Владыкин Многопоточность (1) 17 ноября 2014 6 / 24
7. Общие сведения о параллелизме
Параллелизм в Java
Запуск нескольких JVM на одном или на разных компьютерах
Нет общей памяти
Взаимодействие через файловую систему или сетевое соединение
Запуск нескольких потоков внутри JVM
Есть общая память
Обширная поддержка в языке и стандартной библиотеке
Алексей Владыкин Многопоточность (1) 17 ноября 2014 6 / 24
8. Общие сведения о параллелизме
Проблемы параллельных программ
Гонка (race condition)
Взаимная блокировка (deadlock)
Алексей Владыкин Многопоточность (1) 17 ноября 2014 7 / 24
10. Управление потоками
java.lang.Thread
Потоки представлены экземплярами класса java.lang.Thread
String getName()
long getId()
boolean isDaemon()
StackTraceElement[] getStackTrace()
ThreadGroup getThreadGroup()
Алексей Владыкин Многопоточность (1) 17 ноября 2014 9 / 24
11. Управление потоками
Thread dump
Список всех потоков с их состояниями и stack trace’ами
Ctrl+Break или Ctrl+
jps -l, затем jstack PID
Кнопка в IDE
Алексей Владыкин Многопоточность (1) 17 ноября 2014 10 / 24
12. Управление потоками
Создание потока: подкласс Thread
Thread thread = new Thread () {
@Override
public void run() {
// do some work
}
}
Алексей Владыкин Многопоточность (1) 17 ноября 2014 11 / 24
13. Управление потоками
Создание потока: Runnable
Runnable runnable = new Runnable () {
@Override
public void run() {
// do some work
}
};
Thread thread = new Thread(runnable );
Алексей Владыкин Многопоточность (1) 17 ноября 2014 12 / 24
14. Управление потоками
Жизненный цикл потока
Создание объекта Thread
Запуск
thread.start()
Работа
выполняется метод run(), thread.isAlive() == true
Завершение
метод run() закончился или бросил исключение
Завершенный поток нельзя перезапустить
Алексей Владыкин Многопоточность (1) 17 ноября 2014 13 / 24
15. Управление потоками
Прерывание потока
thread.interrupt()
Если поток находится в ожидании (sleep, join, wait), то
ожидание прерывается исключением InterruptedException
Иначе у потока просто устанавливается флаг interrupted
флаг проверяется методами interrupted() и isInterrupted()
проверять флаг и завершать поток надо самостоятельно
thread.join()
Алексей Владыкин Многопоточность (1) 17 ноября 2014 14 / 24
17. Синхронизация потоков
Возможности встроенной синхронизации
Взаимное исключение
(пока один поток что-то делает, другие не могут ему помешать)
Ожидание и уведомление
(поток ожидает уведомлений от других потоков)
Алексей Владыкин Многопоточность (1) 17 ноября 2014 16 / 24
18. Синхронизация потоков
Ключевое слово synchronized
Синхронизованный метод
public synchronized void doSomething () {
// ...
}
Синхронизованный блок внутри метода
public void doSomething () {
synchronized (obj) {
// ...
}
}
Алексей Владыкин Многопоточность (1) 17 ноября 2014 17 / 24
19. Синхронизация потоков
Ключевое слово synchronized
Синхронизация блоков — по монитору указанного объекта
Синхронизация методов — по монитору текущего объекта (this)
Синхронизация статических методов — по монитору класса
Алексей Владыкин Многопоточность (1) 17 ноября 2014 18 / 24
20. Синхронизация потоков
Ожидание и уведомления
Допустимо только внутри synchronized
void wait()
void wait(long millis)
void wait(long millis, int nanos)
void notify()
void notifyAll()
Алексей Владыкин Многопоточность (1) 17 ноября 2014 19 / 24
22. Модель памяти
Атомарность
Чтение и запись полей всех типов, кроме long и double,
происходит атомарно
Если поле объявлено с модификатором volatile, то атомарно
читаются и пишутся даже long и double
Алексей Владыкин Многопоточность (1) 17 ноября 2014 21 / 24
23. Модель памяти
Видимость
Изменения значений полей, сделанные одним потоком, могут
быть не видны в другом потоке
Изменения, сделанные одним потоком, могут быть видны в
другом потоке в ином порядке
Правила формализованы при помощи отношения happens-before
Семантика final
Алексей Владыкин Многопоточность (1) 17 ноября 2014 22 / 24
24. Модель памяти
happens-before
Запись volatile-поля happens-before чтения этого поля
Освобождение монитора happens-before захват того же
монитора
thread.start() happens-before thread.run()
Завершение thread.run() happens-before выход из
thread.join()
. . .
Алексей Владыкин Многопоточность (1) 17 ноября 2014 23 / 24
25. Что сегодня узнали
Какие бывают виды параллелизма и как они поддерживаются в
Java
Как в Java запускать и останавливать потоки
Какие в Java есть встроенные в язык средства синхронизации
потоков
Что такое Java Memory Model
Алексей Владыкин Многопоточность (1) 17 ноября 2014 24 / 24