Upload
cs-center
View
53
Download
2
Embed Size (px)
Citation preview
Многопоточность в Java: основы
Алексей Владыкин
14 ноября 2016
Алексей Владыкин Многопоточность (1) 14 ноября 2016 1 / 25
1 Общие сведения о параллелизме
2 Управление потоками
3 Синхронизация потоков
4 Модель памяти
5 Советы
Алексей Владыкин Многопоточность (1) 14 ноября 2016 2 / 25
Общие сведения о параллелизме
Алексей Владыкин Многопоточность (1) 14 ноября 2016 3 / 25
Общие сведения о параллелизме
Мотивация
Одновременное выполнение нескольких действий(например, отрисовка пользовательского интерфейса и передачафайлов по сети)
Ускорение вычислений(при наличии нескольких вычислительных ядер)
Алексей Владыкин Многопоточность (1) 14 ноября 2016 4 / 25
Общие сведения о параллелизме
Закон Амдала
S(N) =1
(1− P) + PN
S — ускорение (speedup)P — доля вычислений, которые возможно распараллелитьN — количество вычислительных ядер
Алексей Владыкин Многопоточность (1) 14 ноября 2016 5 / 25
Общие сведения о параллелизме
Параллелизм в Java
Запуск нескольких JVM на одном или на разных компьютерахНет общей памятиВзаимодействие через файловую систему или сетевое соединение
Запуск нескольких потоков внутри JVMЕсть общая памятьОбширная поддержка в языке и стандартной библиотеке
Алексей Владыкин Многопоточность (1) 14 ноября 2016 6 / 25
Общие сведения о параллелизме
Параллелизм в Java
Запуск нескольких JVM на одном или на разных компьютерахНет общей памятиВзаимодействие через файловую систему или сетевое соединение
Запуск нескольких потоков внутри JVMЕсть общая памятьОбширная поддержка в языке и стандартной библиотеке
Алексей Владыкин Многопоточность (1) 14 ноября 2016 6 / 25
Управление потоками
Алексей Владыкин Многопоточность (1) 14 ноября 2016 7 / 25
Управление потоками
java.lang.Thread
Потоки представлены экземплярами класса java.lang.Thread
String getName()
long getId()
boolean isDaemon()
StackTraceElement[] getStackTrace()
Алексей Владыкин Многопоточность (1) 14 ноября 2016 8 / 25
Управление потоками
Thread dump
Список всех потоков с их состояниями и stack trace’ами
Ctrl+Break или Ctrl+\
jps -l, затем jstack PID
Кнопка в IDE
Алексей Владыкин Многопоточность (1) 14 ноября 2016 9 / 25
Управление потоками
Создание потока: подкласс Thread
Thread thread = new Thread () {
@Overridepublic void run() {
// do some work}
}
Алексей Владыкин Многопоточность (1) 14 ноября 2016 10 / 25
Управление потоками
Создание потока: Runnable
Runnable runnable = () -> {// do some work
};
Thread thread = new Thread(runnable );
Алексей Владыкин Многопоточность (1) 14 ноября 2016 11 / 25
Управление потоками
Жизненный цикл потока
Создание объекта Thread
Запускthread.start()
Работавыполняется метод run(), thread.isAlive() == true
Завершениеметод run() закончился или бросил исключение
Завершенный поток нельзя перезапустить
Алексей Владыкин Многопоточность (1) 14 ноября 2016 12 / 25
Управление потоками
Прерывание потока
thread.interrupt()
Если поток находится в ожидании (sleep, join, wait), тоожидание прерывается исключением InterruptedException
Иначе у потока просто устанавливается флаг interruptedфлаг проверяется методами interrupted() и isInterrupted()проверять флаг и завершать поток надо самостоятельно
thread.join()
Алексей Владыкин Многопоточность (1) 14 ноября 2016 13 / 25
Синхронизация потоков
Алексей Владыкин Многопоточность (1) 14 ноября 2016 14 / 25
Синхронизация потоков
Возможности встроенной синхронизации
Взаимное исключение(пока один поток что-то делает, другие не могут ему помешать)
Ожидание и уведомление(поток ожидает уведомлений от других потоков)
Алексей Владыкин Многопоточность (1) 14 ноября 2016 15 / 25
Синхронизация потоков
Ключевое слово synchronized
Синхронизованный метод
public synchronized void doSomething () {// ...
}
Синхронизованный блок внутри метода
public void doSomething () {synchronized (obj) {
// ...}
}
Алексей Владыкин Многопоточность (1) 14 ноября 2016 16 / 25
Синхронизация потоков
Ключевое слово synchronized
Синхронизация блоков — по указанному объекту
Синхронизация методов — по текущему объекту (this)
Синхронизация статических методов — по классу
Алексей Владыкин Многопоточность (1) 14 ноября 2016 17 / 25
Синхронизация потоков
Взаимное исключение
Только один поток может исполнять метод или блок,синхронизированный по данному объекту
Остальные потоки будут ждать
Можно синхронизироваться на одном объекте, а по фактуработать с другим
Алексей Владыкин Многопоточность (1) 14 ноября 2016 18 / 25
Синхронизация потоков
Взаимное исключение
class C {synchronized void foo() {}synchronized void bar() {}static synchronized void baz() {}
}
c1.foo() c1.bar() c2.foo() C.baz()c1.foo() 8 8
c1.bar() 8 8
c2.foo() 8
C.baz() 8
Алексей Владыкин Многопоточность (1) 14 ноября 2016 19 / 25
Синхронизация потоков
Ожидание и уведомления
Допустимо только внутри synchronized по этому же объекту
void wait()void wait(long millis)void wait(long millis, int nanos)
void notify()void notifyAll()
Алексей Владыкин Многопоточность (1) 14 ноября 2016 20 / 25
Модель памяти
∀x,y ∈ Ai, z ∈ (Ci − Ci−1) : xsswi−−−→ y
hbi−−→ z⇒ (∀j > i : xswj−−→ y)
Алексей Владыкин Многопоточность (1) 14 ноября 2016 21 / 25
Модель памяти
Атомарность
Чтение и запись полей всех типов, кроме long и double,происходит атомарно
Если поле объявлено с модификатором volatile, то атомарночитаются и пишутся даже long и double
Алексей Владыкин Многопоточность (1) 14 ноября 2016 22 / 25
Модель памяти
Видимость
Изменения значений полей, сделанные одним потоком, могутбыть не видны в другом потоке
Изменения, сделанные одним потоком, могут быть видны вдругом потоке в ином порядке
Правила формализованы при помощи отношения happens-before
Семантика final
Алексей Владыкин Многопоточность (1) 14 ноября 2016 23 / 25
Модель памяти
happens-before
Запись volatile-поля happens-before чтения этого поля
Освобождение объекта happens-before захват того же объекта
thread.start() happens-before thread.run()
Завершение thread.run() happens-before выход изthread.join()
. . .
Алексей Владыкин Многопоточность (1) 14 ноября 2016 24 / 25
Советы
Четко разделяйте, где приватные данные потока, а где общие длянескольких потоковМинимизируйте изменения состояния;подумайте о том, чтобы сделать свои объекты immutableИнкапсулируйте синхронизацию в реализации классаЕсли это невозможно, то явно документируйте требования квнешней синхронизацииСначала сделайте программу правильной (и простой), а потомускоряйте и распараллеливайте
Алексей Владыкин Многопоточность (1) 14 ноября 2016 25 / 25