2.86M
Category: programmingprogramming

Многопоточность. Процесс и поток

1.

Многопоточность
astondevs.ru

2.

Процесс и поток
Процесс - это совокупность кода и данных, разделяющих общее
виртуальное адресное пространство.
Поток - это одна единица исполнения кода. Каждый поток последовательно
выполняет инструкции процесса, которому он принадлежит, параллельно с
другими потоками этого процесса.

3.

Thread
Thread является классом в Java, который предоставляет основные функциональные
возможности для работы с потоками.
Для создания потока можно создать новый экземпляр класса Thread и передать ему объект,
реализующий интерфейс Runnable или переопределить метод run() внутри класса Thread.
Метод run() содержит код, который будет выполняться в отдельном потоке.
Thread thread = new Thread(new Runnable() {
public void run() {
// код, выполняемый в отдельном потоке
}
});
thread.start();

4.

Runnable
• Runnable является функциональным интерфейсом, предназначенным для работы с потоками
выполнения.
• Он определяет единственный метод run(), в котором размещается код, который будет выполняться
в потоке.
• Runnable объект может быть передан в конструктор класса Thread или использован вместе с
исполнителем (Executor).
Runnable runnable = new Runnable() {
public void run() {
// код, выполняемый в отдельном потоке
}
};
Thread thread = new Thread(runnable);
thread.start();

5.

Callable
Callable также является функциональным
интерфейсом, появившимся в Java 5,
который позволяет возвращать
результат выполнения потока.
Он определяет метод call(), который
выполняет задачу и возвращает
результат.
Callable объект может быть передан в
исполнитель (Executor) или
использоваться вместе с Future для
получения результата выполнения
потока.
Callable<Integer> callable = new Callable<Integer>() {
public Integer call() throws Exception {
// код, выполняемый в отдельном потоке
return 42; // возвращаемый результат
}
};
ExecutorService executorService =
Executors.newSingleThreadExecutor();
Future<Integer> future =
executorService.submit(callable);
Integer result = future.get(); // получение результата
выполнения
executorService.shutdown();

6.

Состояния потока
•NEW
A thread that has not yet started is in this
state.
•RUNNABLE
A thread executing in the Java virtual
machine is in this state.
•BLOCKED
A thread that is blocked waiting for a
monitor lock is in this state.
•WAITING
A thread that is waiting indefinitely for
another thread to perform a particular
action is in this state.
•TIMED_WAITING
A thread that is waiting for another
thread to perform an action for up to a
specified waiting time is in this state.
•TERMINATED
A thread that has exited is in this state.

7.

8.

JMM
Java модель памяти (Java Memory Model, JMM) определяет правила и гарантии относительно
того, как потоки взаимодействуют с памятью при выполнении операций чтения и записи
переменных. JMM обеспечивает абстракцию памяти, которая скрывает различия физической
памяти различных аппаратных платформ и обеспечивает согласованное поведение программ
на разных платформах.

9.

Happens before
1.
2.
3.
4.
5.
6.
7.
8.
9.
В рамках одного поток любая операция happens-before любой операцией следующей за ней в исходном
коде
Освобождение лока (unlock) happens-before захват того же лока (lock)
Выход из synhronized блока/метода happens-before вход в synhronized блок/метод на том же мониторе
Запись volatile поля happens-before чтение того же самого volatile поля
Запись значения в final-поле (и, если это поле — ссылка, то ещё и всех переме./.нных, достижимых из
этого поля (dereference-chain)) при конструировании объекта happens-before запись этого объекта в
какую-либо переменную, происходящая вне этого конструктора.
Завершение метода run экземпляра класса Thread happens-before выход из метода join() или
возвращение false методом isAlive() экземпляром того же треда
Вызов метода start() экземпляра класса Thread happens-before начало метода run() экземпляра того же
треда
Завершение конструктора happens-before начало метода finalize() этого класса
Вызов метода interrupt() на потоке happens-before когда поток обнаружил, что данный метод был вызван
либо путем выбрасывания исключения InterruptedException, либо с помощью методов isInterrupted() или
interrupted()

10.

Проблемы многопоточности
Состояние гонки (Race Conditions): Состояние гонки возникает, когда два или более потока
обращаются к общему ресурсу или переменной и пытаются изменить его значения
одновременно. Это может привести к непредсказуемому и некорректному поведению
программы. Для предотвращения состояния гонки следует использовать механизмы
синхронизации, такие как блокировки (lock) или ключевые слова synchronized и volatile.
Проблема видимости потоков (Thread Visibility): В Java модели памяти может возникнуть
проблема видимости, когда один поток вносит изменения в общие переменные, а другой
поток не видит этих изменений. Это может привести к некорректной работе программы.
Чтобы решить проблему видимости, можно использовать ключевое слово volatile,
синхронизацию или другие механизмы синхронизации.
Deadlock (Взаимоблокировка): Deadlock возникает, когда два или более потока
блокируются, ожидая ресурсы, которые контролируют другие потоки, блокированные в свою
очередь. В результате все потоки оказываются заблокированными, и программа зависает.
Для предотвращения deadlock следует правильно управлять порядком блокировки ресурсов
и избегать вложенных блокировок.

11.

Проблемы многопоточности
Интерференция потоков (Thread Interference): Интерференция потоков возникает, когда
два или более потока обновляют общую переменную без синхронизации, что может
привести к непредсказуемым результатам или некорректному состоянию программы. Для
предотвращения интерференции потоков следует использовать синхронизацию или другие
механизмы синхронизации.
Starvation (Голодание): Starvation возникает, когда поток не получает достаточно ресурсов
для своего выполнения из-за предпочтения других потоков. Это может привести к
снижению производительности или замедлению работы приложения. Для предотвращения
голодания потоков следует учитывать приоритеты потоков и справедливо распределять
ресурсы.
Проблемы производительности (Performance Issues): Многопоточные приложения могут
столкнуться с проблемами производительности, такими как излишняя синхронизация,
слишком много потоков, неправильное управление памятью и другие. Правильная
архитектура и оптимизация кода могут помочь улучшить производительность
многопоточных приложений.

12.

Synchronized
Java-ключевое слово synchronized используется для обозначения блока кода или метода,
который должен быть выполнен только одним потоком в определенное время. Ключевое слово
synchronized обеспечивает механизм синхронизации для предотвращения состояния гонки и
обеспечения правильной видимости изменений в многопоточной среде.
Ключевое слово synchronized обеспечивает атомарность операций чтения/записи и
упорядочивание выполнения операций между потоками. Оно является мощным инструментом
для предотвращения проблем многопоточности, но также может влиять на производительность
приложения. Поэтому следует использовать его с осторожностью и только там, где это
действительно необходимо.

13.

Synchronized
Синхронизация блока кода:
•Можно определить блок кода, который будет выполнен только одним потоком в
определенный момент времени.
•Объект, указанный в скобках, является монитором, или блокировкой, и используется для
определения области синхронизации. Если необходима синхронизация на основе объекта, то
этот объект обычно является общим ресурсом, к которому обращаются потоки.
•Только один поток может находиться внутри синхронизированного блока кода с тем же
монитором в любой момент времени. Остальные потоки, которые пытаются войти в этот блок,
будут заблокированы и ожидать, пока монитор не будет освобожден.
synchronized (объект) {
// блок кода, который требует синхронизации
}

14.

Synchronized
Синхронизация метода:
• Можно объявить метод с ключевым словом synchronized, чтобы гарантировать, что только
один поток будет выполнять этот метод в данный момент времени.
• При объявлении метода с ключевым словом synchronized монитором для синхронизации
становится сам объект экземпляра класса, в котором определен метод. То есть, один поток
может вызывать синхронизированный метод экземпляра класса одновременно.
public synchronized void methodName() {
// код метода
}

15.

Volatile
В Java ключевое слово volatile используется для обозначения переменной, которая может быть видимой и
согласованной между потоками. Когда переменная объявлена с ключевым словом volatile, гарантируется, что
изменения, сделанные одним потоком, будут видны другим потокам.
1. Согласованность видимости (Visibility Coherence): При использовании volatile гарантируется, что изменения,
сделанные одним потоком в переменной, становятся видимыми другим потокам. Это означает, что когда один
поток записывает значение в переменную volatile, оно будет сразу доступно для чтения другим потокам.
2. Отсутствие переупорядочивания (No Reordering): Ключевое слово volatile также предотвращает
переупорядочивание операций чтения и записи вокруг переменной. Это означает, что операции чтения и
записи переменной volatile будут выполняться в том порядке, в котором они были записаны.
3. Нет атомарности (No Atomicity): Важно отметить, что ключевое слово volatile не обеспечивает атомарность
операций чтения и записи. Если операция записи в volatile переменную не является атомарной (например,
увеличение значения), то может потребоваться дополнительная синхронизация для обеспечения
атомарности.

16.

www.andersenlab.com

17.

Пакет Concurrent
ConcurrentHashMap
коллекция типа HashMap, реализующая
интерфейс ConcurrentMap;
CopyOnWriteArrayList
коллекция типа ArrayList с алгоритмом
CopyOnWrite;
CopyOnWriteArraySet
реализация интерфейса Set, использующая
за основу CopyOnWriteArrayList;
ConcurrentNavigableMap расширяет интерфейс NavigableMap;
ConcurrentSkipListMap
аналог коллекции TreeMap с сортировкой
данных по ключу и с поддержкой многопоточности;
ConcurrentSkipListSet
реализация интерфейса Set, выполненная
на основе класса ConcurrentSkipListMap.

18.

Пакет Concurrent
Неблокирующие очереди
○ ConcurrentLinkedQueue
○ ConcurrentLinkedDeque
Блокирующие очереди
○ ArrayBlockingQueue
○ LinkedBlockingQueue
○ LinkedBlockingDeque
○ SynchronousQueue
○ LinkedTransferQueue
○ DelayQueue
○ PriorityBlockingQueue

19.

Пакет Concurrent
AtomicBoolean
AtomicInteger
AtomicLong
AtomicReference

20.

Пакет Concurrent
ReentrantLock
ReentrantReadWriteLock
StampedLock

21.

Пакет Concurrent

22.

Пакет Concurrent
Semaphore
объект синхронизации, ограничивающий количество потоков,
которые могут «войти» в заданный участок кода;
CountDownLatch объект синхронизации, разрешающий вход в заданный участок
кода при выполнении определенных условий;
CyclicBarrier
объект синхронизации типа «барьер», блокирующий
выполнение определенного кода для заданного количества потоков;
Exchanger
объект синхронизации, позволяющий провести обмен данными
между двумя потоками;
Phaser
объект синхронизации типа «барьер», но в отличие от
CyclicBarrier, предоставляет больше гибкости.
English     Русский Rules