26
Многопоточность в Java: основы Алексей Владыкин 14 ноября 2016 Алексей Владыкин Многопоточность (1) 14 ноября 2016 1 / 25

Программирование на Java, осень 2016: Многопоточность в Java: основы

Embed Size (px)

Citation preview

Page 1: Программирование на Java, осень 2016: Многопоточность в Java: основы

Многопоточность в Java: основы

Алексей Владыкин

14 ноября 2016

Алексей Владыкин Многопоточность (1) 14 ноября 2016 1 / 25

Page 2: Программирование на Java, осень 2016: Многопоточность в Java: основы

1 Общие сведения о параллелизме

2 Управление потоками

3 Синхронизация потоков

4 Модель памяти

5 Советы

Алексей Владыкин Многопоточность (1) 14 ноября 2016 2 / 25

Page 3: Программирование на Java, осень 2016: Многопоточность в Java: основы

Общие сведения о параллелизме

Алексей Владыкин Многопоточность (1) 14 ноября 2016 3 / 25

Page 4: Программирование на Java, осень 2016: Многопоточность в Java: основы

Общие сведения о параллелизме

Мотивация

Одновременное выполнение нескольких действий(например, отрисовка пользовательского интерфейса и передачафайлов по сети)

Ускорение вычислений(при наличии нескольких вычислительных ядер)

Алексей Владыкин Многопоточность (1) 14 ноября 2016 4 / 25

Page 5: Программирование на Java, осень 2016: Многопоточность в Java: основы

Общие сведения о параллелизме

Закон Амдала

S(N) =1

(1− P) + PN

S — ускорение (speedup)P — доля вычислений, которые возможно распараллелитьN — количество вычислительных ядер

Алексей Владыкин Многопоточность (1) 14 ноября 2016 5 / 25

Page 6: Программирование на Java, осень 2016: Многопоточность в Java: основы

Общие сведения о параллелизме

Параллелизм в Java

Запуск нескольких JVM на одном или на разных компьютерахНет общей памятиВзаимодействие через файловую систему или сетевое соединение

Запуск нескольких потоков внутри JVMЕсть общая памятьОбширная поддержка в языке и стандартной библиотеке

Алексей Владыкин Многопоточность (1) 14 ноября 2016 6 / 25

Page 7: Программирование на Java, осень 2016: Многопоточность в Java: основы

Общие сведения о параллелизме

Параллелизм в Java

Запуск нескольких JVM на одном или на разных компьютерахНет общей памятиВзаимодействие через файловую систему или сетевое соединение

Запуск нескольких потоков внутри JVMЕсть общая памятьОбширная поддержка в языке и стандартной библиотеке

Алексей Владыкин Многопоточность (1) 14 ноября 2016 6 / 25

Page 8: Программирование на Java, осень 2016: Многопоточность в Java: основы

Управление потоками

Алексей Владыкин Многопоточность (1) 14 ноября 2016 7 / 25

Page 9: Программирование на Java, осень 2016: Многопоточность в Java: основы

Управление потоками

java.lang.Thread

Потоки представлены экземплярами класса java.lang.Thread

String getName()

long getId()

boolean isDaemon()

StackTraceElement[] getStackTrace()

Алексей Владыкин Многопоточность (1) 14 ноября 2016 8 / 25

Page 10: Программирование на Java, осень 2016: Многопоточность в Java: основы

Управление потоками

Thread dump

Список всех потоков с их состояниями и stack trace’ами

Ctrl+Break или Ctrl+\

jps -l, затем jstack PID

Кнопка в IDE

Алексей Владыкин Многопоточность (1) 14 ноября 2016 9 / 25

Page 11: Программирование на Java, осень 2016: Многопоточность в Java: основы

Управление потоками

Создание потока: подкласс Thread

Thread thread = new Thread () {

@Overridepublic void run() {

// do some work}

}

Алексей Владыкин Многопоточность (1) 14 ноября 2016 10 / 25

Page 12: Программирование на Java, осень 2016: Многопоточность в Java: основы

Управление потоками

Создание потока: Runnable

Runnable runnable = () -> {// do some work

};

Thread thread = new Thread(runnable );

Алексей Владыкин Многопоточность (1) 14 ноября 2016 11 / 25

Page 13: Программирование на Java, осень 2016: Многопоточность в Java: основы

Управление потоками

Жизненный цикл потока

Создание объекта Thread

Запускthread.start()

Работавыполняется метод run(), thread.isAlive() == true

Завершениеметод run() закончился или бросил исключение

Завершенный поток нельзя перезапустить

Алексей Владыкин Многопоточность (1) 14 ноября 2016 12 / 25

Page 14: Программирование на Java, осень 2016: Многопоточность в Java: основы

Управление потоками

Прерывание потока

thread.interrupt()

Если поток находится в ожидании (sleep, join, wait), тоожидание прерывается исключением InterruptedException

Иначе у потока просто устанавливается флаг interruptedфлаг проверяется методами interrupted() и isInterrupted()проверять флаг и завершать поток надо самостоятельно

thread.join()

Алексей Владыкин Многопоточность (1) 14 ноября 2016 13 / 25

Page 15: Программирование на Java, осень 2016: Многопоточность в Java: основы

Синхронизация потоков

Алексей Владыкин Многопоточность (1) 14 ноября 2016 14 / 25

Page 16: Программирование на Java, осень 2016: Многопоточность в Java: основы

Синхронизация потоков

Возможности встроенной синхронизации

Взаимное исключение(пока один поток что-то делает, другие не могут ему помешать)

Ожидание и уведомление(поток ожидает уведомлений от других потоков)

Алексей Владыкин Многопоточность (1) 14 ноября 2016 15 / 25

Page 17: Программирование на Java, осень 2016: Многопоточность в Java: основы

Синхронизация потоков

Ключевое слово synchronized

Синхронизованный метод

public synchronized void doSomething () {// ...

}

Синхронизованный блок внутри метода

public void doSomething () {synchronized (obj) {

// ...}

}

Алексей Владыкин Многопоточность (1) 14 ноября 2016 16 / 25

Page 18: Программирование на Java, осень 2016: Многопоточность в Java: основы

Синхронизация потоков

Ключевое слово synchronized

Синхронизация блоков — по указанному объекту

Синхронизация методов — по текущему объекту (this)

Синхронизация статических методов — по классу

Алексей Владыкин Многопоточность (1) 14 ноября 2016 17 / 25

Page 19: Программирование на Java, осень 2016: Многопоточность в Java: основы

Синхронизация потоков

Взаимное исключение

Только один поток может исполнять метод или блок,синхронизированный по данному объекту

Остальные потоки будут ждать

Можно синхронизироваться на одном объекте, а по фактуработать с другим

Алексей Владыкин Многопоточность (1) 14 ноября 2016 18 / 25

Page 20: Программирование на Java, осень 2016: Многопоточность в Java: основы

Синхронизация потоков

Взаимное исключение

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

Page 21: Программирование на Java, осень 2016: Многопоточность в Java: основы

Синхронизация потоков

Ожидание и уведомления

Допустимо только внутри synchronized по этому же объекту

void wait()void wait(long millis)void wait(long millis, int nanos)

void notify()void notifyAll()

Алексей Владыкин Многопоточность (1) 14 ноября 2016 20 / 25

Page 22: Программирование на Java, осень 2016: Многопоточность в Java: основы

Модель памяти

∀x,y ∈ Ai, z ∈ (Ci − Ci−1) : xsswi−−−→ y

hbi−−→ z⇒ (∀j > i : xswj−−→ y)

Алексей Владыкин Многопоточность (1) 14 ноября 2016 21 / 25

Page 23: Программирование на Java, осень 2016: Многопоточность в Java: основы

Модель памяти

Атомарность

Чтение и запись полей всех типов, кроме long и double,происходит атомарно

Если поле объявлено с модификатором volatile, то атомарночитаются и пишутся даже long и double

Алексей Владыкин Многопоточность (1) 14 ноября 2016 22 / 25

Page 24: Программирование на Java, осень 2016: Многопоточность в Java: основы

Модель памяти

Видимость

Изменения значений полей, сделанные одним потоком, могутбыть не видны в другом потоке

Изменения, сделанные одним потоком, могут быть видны вдругом потоке в ином порядке

Правила формализованы при помощи отношения happens-before

Семантика final

Алексей Владыкин Многопоточность (1) 14 ноября 2016 23 / 25

Page 25: Программирование на Java, осень 2016: Многопоточность в Java: основы

Модель памяти

happens-before

Запись volatile-поля happens-before чтения этого поля

Освобождение объекта happens-before захват того же объекта

thread.start() happens-before thread.run()

Завершение thread.run() happens-before выход изthread.join()

. . .

Алексей Владыкин Многопоточность (1) 14 ноября 2016 24 / 25

Page 26: Программирование на Java, осень 2016: Многопоточность в Java: основы

Советы

Четко разделяйте, где приватные данные потока, а где общие длянескольких потоковМинимизируйте изменения состояния;подумайте о том, чтобы сделать свои объекты immutableИнкапсулируйте синхронизацию в реализации классаЕсли это невозможно, то явно документируйте требования квнешней синхронизацииСначала сделайте программу правильной (и простой), а потомускоряйте и распараллеливайте

Алексей Владыкин Многопоточность (1) 14 ноября 2016 25 / 25