0% нашли этот документ полезным (0 голосов)
9 просмотров61 страница

Drip Java Lecture 11

Загружено:

a.sidnevart
Авторское право
© All Rights Reserved
Мы серьезно относимся к защите прав на контент. Если вы подозреваете, что это ваш контент, заявите об этом здесь.
Доступные форматы
Скачать в формате PDF, TXT или читать онлайн в Scribd
0% нашли этот документ полезным (0 голосов)
9 просмотров61 страница

Drip Java Lecture 11

Загружено:

a.sidnevart
Авторское право
© All Rights Reserved
Мы серьезно относимся к защите прав на контент. Если вы подозреваете, что это ваш контент, заявите об этом здесь.
Доступные форматы
Скачать в формате PDF, TXT или читать онлайн в Scribd

Java Лекция 11

Работа с Concurrency

Денис Син
Программа
модуля Основы работы с потоками и их устройство
Рассмотрим что такое потоки и процессы, когда,
как и зачем их использовать

Использование потоков в реальном коде


Разберем что предлагает библиотека Java для
работы с потоками

Продвинутые темы
Изучим Java memory model и посмотрим на
виртуальные потоки

2
План лекции
Примитивы синхронизации
Посмотрим, что предоставляет нам пакет
[Link]

Потокобезопасные коллекции и atomic


Разберемся как и когда использовать
коллекции из [Link]

ThreadPool и Executors
Изучим что такое и как работать с пулом
потоков

CompletableFuture
Как удобно можно запускать многопоточные
программы

3
План лекции
Примитивы синхронизации и atomic
Посмотрим, что предоставляет нам пакет
[Link]

Потокобезопасные коллекции
Разберемся как и когда использовать
коллекции из [Link]

ThreadPool и Executors
Изучим что такое и как работать с пулом
потоков

CompletableFuture
Как удобно можно запускать многопоточные
программы

4
[Link]
Locks

Зачем нам нужны какие-то


Lock есть же synchronized?

6
Locks Плюсы

Locks API дает возможность


расширять блок синхронизации

Synchronized не гарантирует fairness

tryLock() – позволяет ожидать


блокировку с timeout

7
Fairness
1 2 3

Поочередный захват блокировки


несколькими потоками

Lock

8
Locks

Паттерн использования

9
ReentrantLock

Один поток может брать


блокировку несколько раз

Реализация интерфейса Lock

Для гарантии fairness true в


конструкторе

10
ReadWriteLock

Несколько потоков могут брать Thread1


один ReadLock

ReadLock
Если какой-то поток взял WriteLock, Thread2

то другие блокируются

Thread3
Оптимальнее запросы на чтение

Thread4 WriteLock

11
ReadWriteLock

Несколько потоков могут брать Thread1


один ReadLock

ReadLock
Если какой-то поток взял WriteLock, Thread2

то другие блокируются

Thread3
Оптимальнее запросы на чтение

Thread4 WriteLock

12
ReadWriteLock

Несколько потоков могут брать


один ReadLock

Если какой-то поток взял WriteLock,


то другие блокируются

Оптимальнее запросы на чтение

13
Condition
Объект с условием, позволяет
блокировать поток

Поток блокируется до выполнения


условия

Нотифицирует другие потоки, чтобы


те разблокировались

14
Condition

Реализация блокирующей очереди

В очередь можно вставлять до


capactity элементов, дальше поток
заблокируется

Если очередь пуста то метод poll()


заблокирует поток

15
Дополнительные примитивы
синхронизации
CountDownLatch
Есть счетчик, как только он
опускается до 0 блокировка
снимается

countDown() – уменьшает
значение счетчика

await() – блокирует поток,


пока счетчик не равен 0

17
CountDownLatch
Есть счетчик, как только он
опускается до 0 блокировка
снимается

Блокируем один тред пока


другие треды не закончат
свои задачи

18
CyclicBarrier

Похож на CountDownLatch

Барьер можно
переиспользовать

19
CyclicBarrier

Похож на CountDownLatch

Барьер можно
переиспользовать

20
Semaphore
Есть счетчик, как только он
опускается до 0 блокировка
снимается

Блокируем один тред пока


другие треды не закончат
свои задачи

21
Semaphore
Есть счетчик, как только он
опускается до 0 блокировка
снимается

Блокируем один тред пока


другие треды не закончат
свои задачи

22
План лекции
Примитивы синхронизации и atomic
Посмотрим, что предоставляет нам пакет
[Link]

Потокобезопасные коллекции
Разберемся как и когда использовать
коллекции из [Link]

ThreadPool и Executors
Изучим что такое и как работать с пулом
потоков

CompletableFuture
Как удобно можно запускать многопоточные
программы

23
Atomics
Неблокирующие алгоритмы

Минусы Compare and swap Atomics и неблокирующие


синхронизации коллекции
Когда много потоков Можно использовать В Java есть Atomic переменные
конкурируют за блокировку неблокирующие алгоритмы, и специальные неблокирующие
тратится много ресурсов на их основанные на cas операциях коллекции
синхронизацию

25
Atomics

Основаны на cas операциях AtomicBoolean AtomicInteger AtomicLongArray AtomicLong

Могут быть использованы, как AtomicReferenceArray AtomicReference


AtomicIntegerArray
volatile переменные

26
Atomics

Основаны на cas операциях

Могут быть использованы, как


volatile переменные

27
Потокобезопасные коллекции
Synchronized
коллекции

[Link]…()

Возвращает коллекцию, операции


которой использоуют synchronized

Опять блокировки -> снижение


перформанса

29
CopyOnWriteArrayList

На каждую операцию модификации


Old array
add, remove создается копия списка

Хорошо работает, когда на одну New array

операцию записи приходится много


операций чтения

Read Write

Thread 1 Thread 2

30
ConcurrentHashMap

Замена HashMap Имеет атомарные Используется при


методы кэшировании
Не блокируется при чтении и
редко блокируется при записи • putIfAbsent(key, value) В бэкенд сервисах часто
• remove(key, value) используется для in memory
• replace(key, oldValue, newValue) кэша

31
ConcurrentSkipListMap

Замена TreeMap Имеет доп. методы Наследуется от


ConcurrentNavigableMap
Гарантируется среднее время
операций за O(logn) • ceilingEntry/Key
• floorEntry/Key

32
Producer consumer
Producer
consumer
Producer – создает и кладет
объекты в buffer
Produer Consumer
Consumer – читает и обрабатывает
объекты из buffer

34
Сложности

Producer и Consumer может быть Produer

много Consumer

У producer и consumer может быть


разная скорость Produer

Consumer
Нужно уметь синхронизировать
consumer, чтобы они не
Produer
обрабатывали сообщения 2 раза

35
BlockingQueue
Интерфейс, позволяющий
использовать очередь не беспокоясь о
синхронизации

put() – блокирует поток если


очередь полная

take() – блокирует поток если


очередь пустая

36
Пример с
condition

37
План лекции
Примитивы синхронизации и atomic
Посмотрим, что предоставляет нам пакет
[Link]

Потокобезопасные коллекции
Разберемся как и когда использовать
коллекции из [Link]

ThreadPool и Executors
Изучим что такое и как работать с пулом
потоков

CompletableFuture
Как удобно можно запускать многопоточные
программы

38
ThreadPool и Executors
Threads in real life

Просто скачиваем картинки

Что не нравится в этом коде?

40
Threads in real life

Приходится писать однотипный код

Каждый раз создается новый поток

Поток создавать дорого

А если бы картинок было бы 1К

41
ThreadPool
Что за бассейн?

42
ThreadPool
Набор потоков, который создается
сразу при старте

Потоки переиспользуются

После использования поток опять


кладется в pool и не создается по
новой

43
ExecutorService
Использует пул потоков

Использует блокирующую очередь

Задачи помещаются в очередь и


распределяются по потокам

44
ExecutorService
Future<?> submit(Runnable) – отправляет задачу на выполнение без
возвращаемого значения

Future<T> submit(Callable<T>) – отправляет задачу на выполнение с


возвращаемым значением

List<Future<T>> invokeAll(Collection<? Extends Callable<T>> –


отправляет несколько задач на выполнение

Future<T> invokeAny(Collection<? Extends Callable<T>> –


отправляет несколько задач на выполение и возвращает
результат одного которое закончится успешно

45
ExecutorService

[Link]() – блокирует поток, пока


задача не завершится

46
Future
boolean isDone()– выполнилась ли задача у ExecutorService

boolean cancel(boolean)– говорит ExecutorService прекратить выполнение


операции

boolean isCanceled() – отменена ли была задача

V get() – блокирует поток, пока ExecutorService не выполнит


задачу

V get(long, TimeUnit) – выбросит TimeoutException, если задача


не выполнится за переданное время

47
ExecutorService

48
Executors
FixedThreadPool – Пул с фиксированным кол – вом потоков
Класс с методами создания разных
реализаций ExecutorService
SingleThreadPool – Пул с одним потоком

Для разных целей используются свои


реализации CachedThreadPool – Кэширует потоки в рамках небольшого отрезка
времени

ScheduledThreadPool – Ставит задачу на время

49
План лекции
Примитивы синхронизации и atomic
Посмотрим, что предоставляет нам пакет
[Link]

Потокобезопасные коллекции
Разберемся как и когда использовать
коллекции из [Link]

ThreadPool и Excecutors
Изучим что такое и как работать с пулом
потоков

CompletableFuture
Как удобно можно запускать многопоточные
программы

50
CompletableFuture
CompletableFuture

Позволяет еще легче писать


ассинхронный код

Есть возможность писать с


использованием ExecutorService

52
CompletableFuture
boolean isDone()– проверяет записан ли результат задачи в
completableFuture

T get() – блокирует поток и ждет результата выполнения задачи

T join()– то же что и get(), но бросает CompletionException

T getNow(T valueIfAbsent)– возвращает значение либо


valueIfAbsent если его еще нет

V get(long, TimeUnit) – get() с timeout

53
CompletableFuture запуск задач
static <U> CompletableFuture<U> supplyAsync(Supplier<U> ) - Запускается задача с функцией supplier, и результат
выполнения записывается во фьючерс

static <U> CompletableFuture<U> supplyAsync(Supplier<U> , ExecutorService)– Запускается задача с функцией supplier, на


переданном ExecutorService

static CompletableFuture<Void> runAsync(Runnable)

static CompletableFuture<Void> runAsync(Runnbale, ExecutorService) - аналоги supplyAsync, но с Runnable

54
CompletableFuture обработка результата
CompletableFuture<U> thenApply(Function<? super T,? extends U> fn) – функция, которая принимает значение из
первого future, обрабатывает его и записывает нового значение в результирующий future

CompletableFuture<Void> thenAccept(Consumer<? super T> block) – функция принимает значение из первого future и
обрабатывает его без возвращаемого значения

static CompletableFuture<Object> anyOf(CompletableFuture<?>... cfs) – Возвращает новый future, который завершится когда
хотя-бы один из данных завершается

static CompletableFuture<Object> allOf(CompletableFuture<?>... cfs) – Возвращает новый future, который завершится когда
все из данных завершатся

55
CompletableFuture

Позволяет еще легче писать


ассинхронный код

Есть возможность писать с


использованием ExecutorService

56
CallbackHell

Происходит, когда много колбеков


передаются в лямбды

CompletableFuture делает такой код


легче для восприятия

57
CallbackHell

Происходит, когда много колбеков


передаются в лямбды

CompletableFuture делает такой код


легче для восприятия

58
Итоги Synchronized Locks
Примитивы
синхронизации

Неблокирующие Потокобезопасные
Atomics/CAS
алгоритмы коллекции

ThreadPool CompletableFuture

59
Доп. ресурсы

[Link] - статья про синхронизаторы

[Link] - статья про Locks

[Link] - статья про CompletableFuture

[Link] - статья про CompletableFuture

[Link] - обзор [Link]

[Link] - статься про ExecutorService

60
Всем больше Java

Вам также может понравиться