Skip to content

Instantly share code, notes, and snippets.

@andreikastsiuk
Forked from vchernogorov/_readme.md
Created May 5, 2022 20:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andreikastsiuk/e6e521e41919e05a94162f4668f632e0 to your computer and use it in GitHub Desktop.
Save andreikastsiuk/e6e521e41919e05a94162f4668f632e0 to your computer and use it in GitHub Desktop.
Многопоточность в Java

Понятия многопоточности

  1. Monitor - высокоуровневый механизм взаимодействия и синхронизации процессов, обеспечивающий доступ к неразделяемым ресурсам.

    • При многозадачности, основанной на мониторах, компилятор или интерпретатор прозрачно для программиста вставляет код блокировки-разблокировки в оформленные соответствующим образом процедуры, избавляя программиста от явного обращения к примитивам синхронизации.
  2. Semaphore - семафор, самый простой тип блокировки, ограничивает количество потоков, которые могут войти в заданный участок кода.

    • Семафоры используются для синхронизации и защиты передачи данных через разделяемую память, а также для синхронизации работы процессов и потоков.
  3. Mutex - двоичный простейший семафор, который может находиться в одном из двух состояний: отмеченном или неотмеченном. Он отличается от семафора тем, что только владеющий им поток может его освободить, т.е. перевести в отмеченное состояние.

    • Задача мьютекса — защита объекта от доступа к нему других потоков, отличных от того, который завладел мьютексом.
    • В каждый конкретный момент только один поток может владеть объектом, защищённым мьютексом.
    • Если другому потоку будет нужен доступ к переменной, защищённой мьютексом, то этот поток блокируется до тех пор, пока мьютекс не будет освобождён.
  4. Reentrant mutex - мьютекс, который может быть залочен несколько раз одиним и тем же процессом/потоком без создания взаимной блокировки.

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

    • Мягкая блокировка - каждый поток пытается получить блокировку перед доступом к соответствующему разделямому ресурсу.
    • Обязательная блокировка - попытка несанкционированного доступа к заблокированному ресурсу будет прервана, через создание исключения в потоке, который пытался получить доступ.
  6. Spinlock - тип блокировки, который заставляет поток в бесконечном цикле пытаться получить доступ к блокировке.

    • Так как поток остается активным но не выполянет полезной работы, то использование данной блокировки не эффективно.
  7. Deadlock - взаимное исключение, блокировка, при которой несколько процессов находятся в состоянии бесконечного ожидания ресурсов, занятых самими этими процессами.

  8. Livelock - взаимное исключение, блокировка, при которой несколько процессов находятся в состоянии бесконечного зацикливания и не производят полезной работы.

  9. Process - процесс обладает автономной средой выполнения.

    • Каждый процесс, в частности, имеет собственную область памяти.
    • Процесс обычно воспринимается, как синоним выполнению программы или приложения. Однако бывает, что одна приложения занимает несколько процессов.
    • Большинство реализаций JVM запускаются в едином процессе.
    • Java приложение может создать дополнительный процесс с помощью ProcessBuilder объекта.
  10. Thread - потоки иногда называют легковесными процессами (lightweight processes). Потоки существуют внутри процесса - каждый процесс обладает хотя бы одним потоком.

    • Потоки делят ресурсы процесса, включая память и открытые файлы.
    • Приложение может быть как однопоточным, так и многопоточным, но всегда существует единственный "главный" поток, с которого запускается приложение.
  11. Interrupt - прерывание является указанием потоку остановить выпонение.

  12. Join - позволяет одному потоку ждать окончание выполнения другого потока.

  13. Thread safe - участок кода, который работает корректно как в однопоточной, так и в многопоточной среде.

    • Not thread safe - участок кода, который работает корректо только в однопоточной среде.
  14. Thread affinity - при старте потока, можно указать в рантайм среде, чтобы поток был привязан к определенному ядру.

  15. EDT (Event Dispatching Thread) - специальный поток, используемый для обработки событий из очереди событий. Такой подход является концептом событийно-ориентированного программирования.

    • Такие GUI фреймворки, как, например, AWT или Swing, используют EDT.
  16. Race condition - ошибка проектирования многопоточной системы или приложения, при которой работа системы или приложения зависит от того, в каком порядке выполняются части кода.

  17. Context switches - когда планировщик временно приостанавливает работу потока, чтобы активировать другой поток.

    • Частое явление в приложениях с кучей потоков, что очень дорого им обходится из-за:
    • Сохранение и восстановление выполняемого контекста
    • Непостоянное местоположение в памяти
    • Затрачивание CPU на планирование потоков, которое нужно тратить на их использование.
  18. Atomic action (Атомарная операция) - операция, выполняющаяся как единое целое, либо не выполняющаяся вовсе.

    • Атомарная операция не может быть прервана: она либо выполняется полностьбю, либо не выполняется вовсе.
    • Атомарная операция не производит изменений внешней среды во время выполнения, только по окончании.
    • Атомарная операция открыта влиянию только одного потока.
  19. Happened-before relationship - отношение "выполняется прежде" двух событий, которое гарантирует, что память, записанная событием A будет видна для события B, т.е. событие А завершает свою запись перед тем, как B начнет чтение.

    • Данное отношение транзитивно, иррефлексивно, антисимметрично.
    • Транзитивно - для любых 3-х событий a, b, c, если событие a происходит перед b, и b происходит перед c, тогда a должно происходить перед c.
    • Иррефлексивно - ни одно событие не должно происходить перед собой.
    • Антисимметрично - если событие a должно произойти перед событием b, то обратное невозможно.
  20. Critical section - участок кода, в котором производится доступ к общему ресурсу, который не должен быть одновременно использован более чем одним потоком.

    • Мьютекс является процедурой входа/выхода из критической секции.

Thread объект

  1. sleep() - заставляет поток остановить свое выполнение на указанное время. При этом поток не теряет контроль над монитором.

  2. start() - запускает данный поток из текущего потока.

    • Этот метод вызывает run() метод этого же потока.
  3. run() - наследники Thread должны перегружать данный метод. Он вызывается при старте потока.

  4. interrupt() - прерывает выпонение потока.

    • InterruptedException - данный поток получит это исключение, если произошло успешное прерывание потока.
    • ClosedByInterruptException - если данный поток был заблокирован I/O операцией, то поток получит это исключение по окончанию прерывания.
  5. setPriority() - изменяет приоритет данного потока.

    • Минимальный приоритет - 1, максимальный - 10.
  6. join() - заставляет поток ждать не более чем указанное время, чтобы завершиться.

    • Реализация данного метода использует цикл с вызовом wait(), который вызывается пока isAlive. После завершения потока вызывается notifyAll() метод.
    • Он создан для того, чтобы приложения не использовали методы wait(),notify,notifyAll методы из Thread сущностей, так как это не рекомендованно.
    • Если не указывать время или указать 0, то поток будет ждать вечно чтобы умереть... пичаль.
  7. setDaemon() - отмечает данный поток как поток-демон или пользовательский поток.

    • JVM отрубается если все запущенный потоки являются демонами.
    • Этот метод должен выполняться перед стартом потока.
  8. yield() - указывает планировщику, что текущий поток закончил свое выполнение и готов перейти в пользование процессора. Планировщик однаком может игнорировать это указание.

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

Java инструменты многопоточности

  1. JMM (Java Memory Model) - описывает поведение потоков в среде исполнения Java.

    • Однопоточные программы выолняются псевдопоследовательно, то есть в реальности процессор может выполнять несколько операций за такт, заодно изменив их порядок, однако все зависимости по данным остаются, так что поведение не отличается от последовательного.
  2. java.lang.Thread - каждый поток ассоциируется с объектом этого класса.

    • Thread.sleep() отдает команду текущему потоку приостановить выполнение на указанное время.
    • Thread.interrupted() возвращает true, если выполнение потока было прервано.
    • thread.join() позволяет одному потоку ждать окончания выполнения другого (т.е. текущий ждет выполнения потока thread).
  3. java.lang.Runnable - интерфейс определяет единственный метод run, который должен содержать код, который будет выполняться в потоке.

  4. volatile - данный модификатор указывает компилятору, что чтение перемнной будет производиться прямо из памяти, что позволяет нескольким потокам видеть последнее значение переменной.

  5. java.util.concurrent.locks.Lock - интерфейс, реализации которого предполагают более обширные операции блокировки, чем предоставляемые synchronized методами и блоками.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment