Skip to content

Instantly share code, notes, and snippets.

@andreikastsiuk
Forked from vchernogorov/_readme.md
Created May 5, 2022 20:37
Show Gist options
  • Save andreikastsiuk/e6e521e41919e05a94162f4668f632e0 to your computer and use it in GitHub Desktop.
Save andreikastsiuk/e6e521e41919e05a94162f4668f632e0 to your computer and use it in GitHub Desktop.

Revisions

  1. @vchernogorov vchernogorov revised this gist Apr 22, 2017. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion _readme.md
    Original file line number Diff line number Diff line change
    @@ -4,4 +4,6 @@

    ### Содержание:

    - [Понятия многопоточности](#file-concurrency-concepts-md)
    - [Понятия многопоточности](#file-concurrency-concepts-md)
    - [Java инструменты многопоточности](#file-java-concurrency-tools-md)
    - [`Thread` объект](#file-concurrency-thread-object-md)
  2. @vchernogorov vchernogorov revised this gist Apr 22, 2017. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion _readme.md
    Original file line number Diff line number Diff line change
    @@ -4,4 +4,4 @@

    ### Содержание:

    - [Общее](https://gist.github.com/vchernogorov/cacded15f0617c926234994fd63dc683#file-java-se-general-md)
    - [Понятия многопоточности](#file-concurrency-concepts-md)
  3. @vchernogorov vchernogorov revised this gist Apr 22, 2017. 5 changed files with 62 additions and 63 deletions.
    7 changes: 7 additions & 0 deletions _readme.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,7 @@
    ### Многопоточность в Java

    Данный гист содержит основную информацию, которую нужно знать о Java Standart Edition.

    ### Содержание:

    - [Общее](https://gist.github.com/vchernogorov/cacded15f0617c926234994fd63dc683#file-java-se-general-md)
    11 changes: 11 additions & 0 deletions _sources.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,11 @@
    ### Источники

    1. https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#yield()
    2. https://ru.wikipedia.org/wiki/%D0%9C%D1%8C%D1%8E%D1%82%D0%B5%D0%BA%D1%81
    3. https://ru.wikipedia.org/wiki/%D0%9C%D0%BE%D0%BD%D0%B8%D1%82%D0%BE%D1%80_(%D1%81%D0%B8%D0%BD%D1%85%D1%80%D0%BE%D0%BD%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F)
    4. https://en.wikipedia.org/wiki/Happened-before
    5. https://docs.oracle.com/javase/tutorial/essential/concurrency/index.html
    6. https://www.amazon.com/Java-Concurrency-Practice-Brian-Goetz/dp/0321349601/192-1511873-1398145?ie=UTF8&*Version*=1&*entries*=0
    7. https://habrahabr.ru/company/golovachcourses/blog/256883/
    8. http://ru.stackoverflow.com/questions/1271/%D0%9A%D0%BB%D1%8E%D1%87%D0%B5%D0%B2%D0%BE%D0%B5-%D1%81%D0%BB%D0%BE%D0%B2%D0%BE-volatile-%D0%B2-java
    9. https://ru.wikipedia.org/wiki/%D0%90%D1%82%D0%BE%D0%BC%D0%B0%D1%80%D0%BD%D0%B0%D1%8F_%D0%BE%D0%BF%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D1%8F
    64 changes: 1 addition & 63 deletions concurrency.md → concurrency-concepts.md
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,4 @@
    # Concurrency

    ### 1. Общее
    # Понятия многопоточности

    1. **Monitor** - высокоуровневый механизм взаимодействия и синхронизации процессов, обеспечивающий доступ к неразделяемым ресурсам.
    - При многозадачности, основанной на мониторах, компилятор или интерпретатор прозрачно для программиста вставляет код блокировки-разблокировки в оформленные соответствующим образом процедуры, избавляя программиста от явного обращения к примитивам синхронизации.
    @@ -69,63 +67,3 @@

    20. **Critical section** - участок кода, в котором производится доступ к общему ресурсу, который не должен быть одновременно использован более чем одним потоком.
    - Мьютекс является процедурой входа/выхода из критической секции.

    ---

    ### 2. Java-specific

    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` методами и блоками.

    ### 3. 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()`** - указывает планировщику, что текущий поток закончил свое выполнение и готов перейти в пользование процессора. Планировщик однаком может игнорировать это указание.
    - Использование данного метода редко является уместным. Он может использоваться для дебага или тестирования.

    ---

    ### Источники

    1. https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#yield()
    2. https://ru.wikipedia.org/wiki/%D0%9C%D1%8C%D1%8E%D1%82%D0%B5%D0%BA%D1%81
    3. https://ru.wikipedia.org/wiki/%D0%9C%D0%BE%D0%BD%D0%B8%D1%82%D0%BE%D1%80_(%D1%81%D0%B8%D0%BD%D1%85%D1%80%D0%BE%D0%BD%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F)
    4. https://en.wikipedia.org/wiki/Happened-before
    5. https://docs.oracle.com/javase/tutorial/essential/concurrency/index.html
    6. https://www.amazon.com/Java-Concurrency-Practice-Brian-Goetz/dp/0321349601/192-1511873-1398145?ie=UTF8&*Version*=1&*entries*=0
    7. https://habrahabr.ru/company/golovachcourses/blog/256883/
    8. http://ru.stackoverflow.com/questions/1271/%D0%9A%D0%BB%D1%8E%D1%87%D0%B5%D0%B2%D0%BE%D0%B5-%D1%81%D0%BB%D0%BE%D0%B2%D0%BE-volatile-%D0%B2-java
    9. https://ru.wikipedia.org/wiki/%D0%90%D1%82%D0%BE%D0%BC%D0%B0%D1%80%D0%BD%D0%B0%D1%8F_%D0%BE%D0%BF%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D1%8F
    28 changes: 28 additions & 0 deletions concurrency-thread-object.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,28 @@
    # `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()`** - указывает планировщику, что текущий поток закончил свое выполнение и готов перейти в пользование процессора. Планировщик однаком может игнорировать это указание.
    - Использование данного метода редко является уместным. Он может использоваться для дебага или тестирования.

    15 changes: 15 additions & 0 deletions java-concurrency-tools.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,15 @@
    # 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` методами и блоками.
  4. @vchernogorov vchernogorov revised this gist Apr 16, 2017. 1 changed file with 33 additions and 33 deletions.
    66 changes: 33 additions & 33 deletions concurrency.md
    Original file line number Diff line number Diff line change
    @@ -16,71 +16,71 @@
    4. **Reentrant mutex** - мьютекс, который может быть залочен несколько раз одиним и тем же процессом/потоком без создания взаимной блокировки.

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

    6. **Spinlock** - тип блокировки, который заставляет поток в бесконечном цикле пытаться получить доступ к блокировке.
    - Так как поток остается активным но не выполянет полезной работы, то использование данной блокировки не эффективно.
    - Так как поток остается активным но не выполянет полезной работы, то использование данной блокировки не эффективно.

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

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

    9. **Process** - процесс обладает автономной средой выполнения.
    - Каждый процесс, в частности, имеет собственную область памяти.
    - Процесс обычно воспринимается, как синоним выполнению программы или приложения. Однако бывает, что одна приложения занимает несколько процессов.
    - Большинство реализаций JVM запускаются в едином процессе.
    - Java приложение может создать дополнительный процесс с помощью ProcessBuilder объекта.
    9. **Process** - процесс обладает автономной средой выполнения.
    - Каждый процесс, в частности, имеет собственную область памяти.
    - Процесс обычно воспринимается, как синоним выполнению программы или приложения. Однако бывает, что одна приложения занимает несколько процессов.
    - Большинство реализаций JVM запускаются в едином процессе.
    - Java приложение может создать дополнительный процесс с помощью ProcessBuilder объекта.

    10. **Thread** - потоки иногда называют легковесными процессами (lightweight processes). Потоки существуют внутри процесса - каждый процесс обладает хотя бы одним потоком.
    - Потоки делят ресурсы процесса, включая память и открытые файлы.
    - Приложение может быть как однопоточным, так и многопоточным, но всегда существует единственный "главный" поток, с которого запускается приложение.
    - Потоки делят ресурсы процесса, включая память и открытые файлы.
    - Приложение может быть как однопоточным, так и многопоточным, но всегда существует единственный "главный" поток, с которого запускается приложение.

    11. **Interrupt** - прерывание является указанием потоку остановить выпонение.

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

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

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

    15. **EDT (Event Dispatching Thread)** - специальный поток, используемый для обработки событий из очереди событий. Такой подход является концептом событийно-ориентированного программирования.
    - Такие GUI фреймворки, как, например, AWT или Swing, используют EDT.
    - Такие 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** - участок кода, в котором производится доступ к общему ресурсу, который не должен быть одновременно использован более чем одним потоком.
    - Мьютекс является процедурой входа/выхода из критической секции.
    - Мьютекс является процедурой входа/выхода из критической секции.

    ---

    ### 2. Java-specific

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

    2. **`java.lang.Thread`** - каждый поток ассоциируется с объектом этого класса.
    - `Thread.sleep()` отдает команду текущему потоку приостановить выполнение на указанное время.
    - `Thread.interrupted()` возвращает `true`, если выполнение потока было прервано.
    - `thread.join()` позволяет одному потоку ждать окончания выполнения другого (т.е. текущий ждет выполнения потока `thread`).
    - `Thread.sleep()` отдает команду текущему потоку приостановить выполнение на указанное время.
    - `Thread.interrupted()` возвращает `true`, если выполнение потока было прервано.
    - `thread.join()` позволяет одному потоку ждать окончания выполнения другого (т.е. текущий ждет выполнения потока `thread`).

    3. **`java.lang.Runnable`** - интерфейс определяет единственный метод `run`, который должен содержать код, который будет выполняться в потоке.

    @@ -93,28 +93,28 @@
    1. **`sleep()`** - заставляет поток остановить свое выполнение на указанное время. При этом поток не теряет контроль над монитором.

    2. **`start()`** - запускает данный поток из текущего потока.
    - Этот метод вызывает `run()` метод этого же потока.
    - Этот метод вызывает `run()` метод этого же потока.

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

    4. **`interrupt()`** - прерывает выпонение потока.
    - `InterruptedException` - данный поток получит это исключение, если произошло успешное прерывание потока.
    - `ClosedByInterruptException` - если данный поток был заблокирован I/O операцией, то поток получит это исключение по окончанию прерывания.
    - `InterruptedException` - данный поток получит это исключение, если произошло успешное прерывание потока.
    - `ClosedByInterruptException` - если данный поток был заблокирован I/O операцией, то поток получит это исключение по окончанию прерывания.

    5. **`setPriority()`** - изменяет приоритет данного потока.
    - Минимальный приоритет - 1, максимальный - 10.
    - Минимальный приоритет - 1, максимальный - 10.

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

    7. **`setDaemon()`** - отмечает данный поток как поток-демон или пользовательский поток.
    - JVM отрубается если все запущенный потоки являются демонами.
    - Этот метод должен выполняться перед стартом потока.
    - JVM отрубается если все запущенный потоки являются демонами.
    - Этот метод должен выполняться перед стартом потока.

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

    ---

  5. @vchernogorov vchernogorov revised this gist Apr 16, 2017. 1 changed file with 5 additions and 5 deletions.
    10 changes: 5 additions & 5 deletions concurrency.md
    Original file line number Diff line number Diff line change
    @@ -3,15 +3,15 @@
    ### 1. Общее

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

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

    3. **Mutex** - двоичный простейший семафор, который может находиться в одном из двух состояний: отмеченном или неотмеченном. Он отличается от семафора тем, что только владеющий им поток может его освободить, т.е. перевести в отмеченное состояние.
    - Задача мьютекса — защита объекта от доступа к нему других потоков, отличных от того, который завладел мьютексом.
    - В каждый конкретный момент только один поток может владеть объектом, защищённым мьютексом.
    - Если другому потоку будет нужен доступ к переменной, защищённой мьютексом, то этот поток блокируется до тех пор, пока мьютекс не будет освобождён.
    - Задача мьютекса — защита объекта от доступа к нему других потоков, отличных от того, который завладел мьютексом.
    - В каждый конкретный момент только один поток может владеть объектом, защищённым мьютексом.
    - Если другому потоку будет нужен доступ к переменной, защищённой мьютексом, то этот поток блокируется до тех пор, пока мьютекс не будет освобождён.

    4. **Reentrant mutex** - мьютекс, который может быть залочен несколько раз одиним и тем же процессом/потоком без создания взаимной блокировки.

  6. @vchernogorov vchernogorov revised this gist Apr 16, 2017. 1 changed file with 38 additions and 38 deletions.
    76 changes: 38 additions & 38 deletions concurrency.md
    Original file line number Diff line number Diff line change
    @@ -5,69 +5,69 @@
    1. **Monitor** - высокоуровневый механизм взаимодействия и синхронизации процессов, обеспечивающий доступ к неразделяемым ресурсам.
    - При многозадачности, основанной на мониторах, компилятор или интерпретатор прозрачно для программиста вставляет код блокировки-разблокировки в оформленные соответствующим образом процедуры, избавляя программиста от явного обращения к примитивам синхронизации.

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

    1. **Mutex** - двоичный простейший семафор, который может находиться в одном из двух состояний: отмеченном или неотмеченном. Он отличается от семафора тем, что только владеющий им поток может его освободить, т.е. перевести в отмеченное состояние.
    3. **Mutex** - двоичный простейший семафор, который может находиться в одном из двух состояний: отмеченном или неотмеченном. Он отличается от семафора тем, что только владеющий им поток может его освободить, т.е. перевести в отмеченное состояние.
    - Задача мьютекса — защита объекта от доступа к нему других потоков, отличных от того, который завладел мьютексом.
    - В каждый конкретный момент только один поток может владеть объектом, защищённым мьютексом.
    - Если другому потоку будет нужен доступ к переменной, защищённой мьютексом, то этот поток блокируется до тех пор, пока мьютекс не будет освобождён.

    1. **Reentrant mutex** - мьютекс, который может быть залочен несколько раз одиним и тем же процессом/потоком без создания взаимной блокировки.
    4. **Reentrant mutex** - мьютекс, который может быть залочен несколько раз одиним и тем же процессом/потоком без создания взаимной блокировки.

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

    1. **Spinlock** - тип блокировки, который заставляет поток в бесконечном цикле пытаться получить доступ к блокировке.
    6. **Spinlock** - тип блокировки, который заставляет поток в бесконечном цикле пытаться получить доступ к блокировке.
    - Так как поток остается активным но не выполянет полезной работы, то использование данной блокировки не эффективно.

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

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

    1. **Process** - процесс обладает автономной средой выполнения.
    9. **Process** - процесс обладает автономной средой выполнения.
    - Каждый процесс, в частности, имеет собственную область памяти.
    - Процесс обычно воспринимается, как синоним выполнению программы или приложения. Однако бывает, что одна приложения занимает несколько процессов.
    - Большинство реализаций JVM запускаются в едином процессе.
    - Java приложение может создать дополнительный процесс с помощью ProcessBuilder объекта.

    1. **Thread** - потоки иногда называют легковесными процессами (lightweight processes). Потоки существуют внутри процесса - каждый процесс обладает хотя бы одним потоком.
    10. **Thread** - потоки иногда называют легковесными процессами (lightweight processes). Потоки существуют внутри процесса - каждый процесс обладает хотя бы одним потоком.
    - Потоки делят ресурсы процесса, включая память и открытые файлы.
    - Приложение может быть как однопоточным, так и многопоточным, но всегда существует единственный "главный" поток, с которого запускается приложение.

    1. **Interrupt** - прерывание является указанием потоку остановить выпонение.
    11. **Interrupt** - прерывание является указанием потоку остановить выпонение.

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

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

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

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

    1. **Race condition** - ошибка проектирования многопоточной системы или приложения, при которой работа системы или приложения зависит от того, в каком порядке выполняются части кода.
    16. **Race condition** - ошибка проектирования многопоточной системы или приложения, при которой работа системы или приложения зависит от того, в каком порядке выполняются части кода.

    1. **Context switches** - когда планировщик временно приостанавливает работу потока, чтобы активировать другой поток.
    17. **Context switches** - когда планировщик временно приостанавливает работу потока, чтобы активировать другой поток.
    - Частое явление в приложениях с кучей потоков, что очень дорого им обходится из-за:
    + Сохранение и восстановление выполняемого контекста
    + Непостоянное местоположение в памяти
    + Затрачивание CPU на планирование потоков, которое нужно тратить на их использование.

    1. **Atomic action (Атомарная операция)** - операция, выполняющаяся как единое целое, либо не выполняющаяся вовсе.
    18. **Atomic action (Атомарная операция)** - операция, выполняющаяся как единое целое, либо не выполняющаяся вовсе.
    - Атомарная операция не может быть прервана: она либо выполняется полностьбю, либо не выполняется вовсе.
    - Атомарная операция не производит изменений внешней среды во время выполнения, только по окончании.
    - Атомарная операция открыта влиянию только одного потока.

    1. **Happened-before relationship** - отношение "выполняется прежде" двух событий, которое гарантирует, что память, записанная событием A будет видна для события B, т.е. событие А завершает свою запись перед тем, как B начнет чтение.
    19. **Happened-before relationship** - отношение "выполняется прежде" двух событий, которое гарантирует, что память, записанная событием A будет видна для события B, т.е. событие А завершает свою запись перед тем, как B начнет чтение.
    - Данное отношение транзитивно, иррефлексивно, антисимметрично.
    + Транзитивно - для любых 3-х событий a, b, c, если событие a происходит перед b, и b происходит перед c, тогда a должно происходить перед c.
    + Иррефлексивно - ни одно событие не должно происходить перед собой.
    + Антисимметрично - если событие a должно произойти перед событием b, то обратное невозможно.

    1. **Critical section** - участок кода, в котором производится доступ к общему ресурсу, который не должен быть одновременно использован более чем одним потоком.
    20. **Critical section** - участок кода, в котором производится доступ к общему ресурсу, который не должен быть одновременно использован более чем одним потоком.
    - Мьютекс является процедурой входа/выхода из критической секции.

    ---
    @@ -77,55 +77,55 @@
    1. **JMM (Java Memory Model)** - описывает поведение потоков в среде исполнения Java.
    - Однопоточные программы выолняются псевдопоследовательно, то есть в реальности процессор может выполнять несколько операций за такт, заодно изменив их порядок, однако все зависимости по данным остаются, так что поведение не отличается от последовательного.

    1. **`java.lang.Thread`** - каждый поток ассоциируется с объектом этого класса.
    2. **`java.lang.Thread`** - каждый поток ассоциируется с объектом этого класса.
    - `Thread.sleep()` отдает команду текущему потоку приостановить выполнение на указанное время.
    - `Thread.interrupted()` возвращает `true`, если выполнение потока было прервано.
    - `thread.join()` позволяет одному потоку ждать окончания выполнения другого (т.е. текущий ждет выполнения потока `thread`).

    1. **`java.lang.Runnable`** - интерфейс определяет единственный метод `run`, который должен содержать код, который будет выполняться в потоке.
    3. **`java.lang.Runnable`** - интерфейс определяет единственный метод `run`, который должен содержать код, который будет выполняться в потоке.

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

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

    ### 3. Thread

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

    1. **`start()`** - запускает данный поток из текущего потока.
    2. **`start()`** - запускает данный поток из текущего потока.
    - Этот метод вызывает `run()` метод этого же потока.

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

    1. **`interrupt()`** - прерывает выпонение потока.
    4. **`interrupt()`** - прерывает выпонение потока.
    - `InterruptedException` - данный поток получит это исключение, если произошло успешное прерывание потока.
    - `ClosedByInterruptException` - если данный поток был заблокирован I/O операцией, то поток получит это исключение по окончанию прерывания.

    1. **`setPriority()`** - изменяет приоритет данного потока.
    5. **`setPriority()`** - изменяет приоритет данного потока.
    - Минимальный приоритет - 1, максимальный - 10.

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

    1. **`setDaemon()`** - отмечает данный поток как поток-демон или пользовательский поток.
    7. **`setDaemon()`** - отмечает данный поток как поток-демон или пользовательский поток.
    - JVM отрубается если все запущенный потоки являются демонами.
    - Этот метод должен выполняться перед стартом потока.

    1. **`yield()`** - указывает планировщику, что текущий поток закончил свое выполнение и готов перейти в пользование процессора. Планировщик однаком может игнорировать это указание.
    8. **`yield()`** - указывает планировщику, что текущий поток закончил свое выполнение и готов перейти в пользование процессора. Планировщик однаком может игнорировать это указание.
    - Использование данного метода редко является уместным. Он может использоваться для дебага или тестирования.

    ---

    ### Источники

    1. https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#yield()
    1. https://ru.wikipedia.org/wiki/%D0%9C%D1%8C%D1%8E%D1%82%D0%B5%D0%BA%D1%81
    1. https://ru.wikipedia.org/wiki/%D0%9C%D0%BE%D0%BD%D0%B8%D1%82%D0%BE%D1%80_(%D1%81%D0%B8%D0%BD%D1%85%D1%80%D0%BE%D0%BD%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F)
    1. https://en.wikipedia.org/wiki/Happened-before
    1. https://docs.oracle.com/javase/tutorial/essential/concurrency/index.html
    1. https://www.amazon.com/Java-Concurrency-Practice-Brian-Goetz/dp/0321349601/192-1511873-1398145?ie=UTF8&*Version*=1&*entries*=0
    1. https://habrahabr.ru/company/golovachcourses/blog/256883/
    1. http://ru.stackoverflow.com/questions/1271/%D0%9A%D0%BB%D1%8E%D1%87%D0%B5%D0%B2%D0%BE%D0%B5-%D1%81%D0%BB%D0%BE%D0%B2%D0%BE-volatile-%D0%B2-java
    1. https://ru.wikipedia.org/wiki/%D0%90%D1%82%D0%BE%D0%BC%D0%B0%D1%80%D0%BD%D0%B0%D1%8F_%D0%BE%D0%BF%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D1%8F
    2. https://ru.wikipedia.org/wiki/%D0%9C%D1%8C%D1%8E%D1%82%D0%B5%D0%BA%D1%81
    3. https://ru.wikipedia.org/wiki/%D0%9C%D0%BE%D0%BD%D0%B8%D1%82%D0%BE%D1%80_(%D1%81%D0%B8%D0%BD%D1%85%D1%80%D0%BE%D0%BD%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F)
    4. https://en.wikipedia.org/wiki/Happened-before
    5. https://docs.oracle.com/javase/tutorial/essential/concurrency/index.html
    6. https://www.amazon.com/Java-Concurrency-Practice-Brian-Goetz/dp/0321349601/192-1511873-1398145?ie=UTF8&*Version*=1&*entries*=0
    7. https://habrahabr.ru/company/golovachcourses/blog/256883/
    8. http://ru.stackoverflow.com/questions/1271/%D0%9A%D0%BB%D1%8E%D1%87%D0%B5%D0%B2%D0%BE%D0%B5-%D1%81%D0%BB%D0%BE%D0%B2%D0%BE-volatile-%D0%B2-java
    9. https://ru.wikipedia.org/wiki/%D0%90%D1%82%D0%BE%D0%BC%D0%B0%D1%80%D0%BD%D0%B0%D1%8F_%D0%BE%D0%BF%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D1%8F
  7. @vchernogorov vchernogorov created this gist Apr 16, 2017.
    131 changes: 131 additions & 0 deletions concurrency.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,131 @@
    # Concurrency

    ### 1. Общее

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

    1. **Semaphore** - семафор, самый простой тип блокировки, ограничивает количество потоков, которые могут войти в заданный участок кода.
    - Семафоры используются для синхронизации и защиты передачи данных через разделяемую память, а также для синхронизации работы процессов и потоков.

    1. **Mutex** - двоичный простейший семафор, который может находиться в одном из двух состояний: отмеченном или неотмеченном. Он отличается от семафора тем, что только владеющий им поток может его освободить, т.е. перевести в отмеченное состояние.
    - Задача мьютекса — защита объекта от доступа к нему других потоков, отличных от того, который завладел мьютексом.
    - В каждый конкретный момент только один поток может владеть объектом, защищённым мьютексом.
    - Если другому потоку будет нужен доступ к переменной, защищённой мьютексом, то этот поток блокируется до тех пор, пока мьютекс не будет освобождён.

    1. **Reentrant mutex** - мьютекс, который может быть залочен несколько раз одиним и тем же процессом/потоком без создания взаимной блокировки.

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

    1. **Spinlock** - тип блокировки, который заставляет поток в бесконечном цикле пытаться получить доступ к блокировке.
    - Так как поток остается активным но не выполянет полезной работы, то использование данной блокировки не эффективно.

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

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

    1. **Process** - процесс обладает автономной средой выполнения.
    - Каждый процесс, в частности, имеет собственную область памяти.
    - Процесс обычно воспринимается, как синоним выполнению программы или приложения. Однако бывает, что одна приложения занимает несколько процессов.
    - Большинство реализаций JVM запускаются в едином процессе.
    - Java приложение может создать дополнительный процесс с помощью ProcessBuilder объекта.

    1. **Thread** - потоки иногда называют легковесными процессами (lightweight processes). Потоки существуют внутри процесса - каждый процесс обладает хотя бы одним потоком.
    - Потоки делят ресурсы процесса, включая память и открытые файлы.
    - Приложение может быть как однопоточным, так и многопоточным, но всегда существует единственный "главный" поток, с которого запускается приложение.

    1. **Interrupt** - прерывание является указанием потоку остановить выпонение.

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

    1. **Thread safe** - участок кода, который работает корректно как в однопоточной, так и в многопоточной среде.
    - **Not thread safe** - участок кода, который работает корректо только в однопоточной среде.

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

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

    1. **Race condition** - ошибка проектирования многопоточной системы или приложения, при которой работа системы или приложения зависит от того, в каком порядке выполняются части кода.

    1. **Context switches** - когда планировщик временно приостанавливает работу потока, чтобы активировать другой поток.
    - Частое явление в приложениях с кучей потоков, что очень дорого им обходится из-за:
    + Сохранение и восстановление выполняемого контекста
    + Непостоянное местоположение в памяти
    + Затрачивание CPU на планирование потоков, которое нужно тратить на их использование.

    1. **Atomic action (Атомарная операция)** - операция, выполняющаяся как единое целое, либо не выполняющаяся вовсе.
    - Атомарная операция не может быть прервана: она либо выполняется полностьбю, либо не выполняется вовсе.
    - Атомарная операция не производит изменений внешней среды во время выполнения, только по окончании.
    - Атомарная операция открыта влиянию только одного потока.

    1. **Happened-before relationship** - отношение "выполняется прежде" двух событий, которое гарантирует, что память, записанная событием A будет видна для события B, т.е. событие А завершает свою запись перед тем, как B начнет чтение.
    - Данное отношение транзитивно, иррефлексивно, антисимметрично.
    + Транзитивно - для любых 3-х событий a, b, c, если событие a происходит перед b, и b происходит перед c, тогда a должно происходить перед c.
    + Иррефлексивно - ни одно событие не должно происходить перед собой.
    + Антисимметрично - если событие a должно произойти перед событием b, то обратное невозможно.

    1. **Critical section** - участок кода, в котором производится доступ к общему ресурсу, который не должен быть одновременно использован более чем одним потоком.
    - Мьютекс является процедурой входа/выхода из критической секции.

    ---

    ### 2. Java-specific

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

    1. **`java.lang.Thread`** - каждый поток ассоциируется с объектом этого класса.
    - `Thread.sleep()` отдает команду текущему потоку приостановить выполнение на указанное время.
    - `Thread.interrupted()` возвращает `true`, если выполнение потока было прервано.
    - `thread.join()` позволяет одному потоку ждать окончания выполнения другого (т.е. текущий ждет выполнения потока `thread`).

    1. **`java.lang.Runnable`** - интерфейс определяет единственный метод `run`, который должен содержать код, который будет выполняться в потоке.

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

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

    ### 3. Thread

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

    1. **`start()`** - запускает данный поток из текущего потока.
    - Этот метод вызывает `run()` метод этого же потока.

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

    1. **`interrupt()`** - прерывает выпонение потока.
    - `InterruptedException` - данный поток получит это исключение, если произошло успешное прерывание потока.
    - `ClosedByInterruptException` - если данный поток был заблокирован I/O операцией, то поток получит это исключение по окончанию прерывания.

    1. **`setPriority()`** - изменяет приоритет данного потока.
    - Минимальный приоритет - 1, максимальный - 10.

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

    1. **`setDaemon()`** - отмечает данный поток как поток-демон или пользовательский поток.
    - JVM отрубается если все запущенный потоки являются демонами.
    - Этот метод должен выполняться перед стартом потока.

    1. **`yield()`** - указывает планировщику, что текущий поток закончил свое выполнение и готов перейти в пользование процессора. Планировщик однаком может игнорировать это указание.
    - Использование данного метода редко является уместным. Он может использоваться для дебага или тестирования.

    ---

    ### Источники

    1. https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#yield()
    1. https://ru.wikipedia.org/wiki/%D0%9C%D1%8C%D1%8E%D1%82%D0%B5%D0%BA%D1%81
    1. https://ru.wikipedia.org/wiki/%D0%9C%D0%BE%D0%BD%D0%B8%D1%82%D0%BE%D1%80_(%D1%81%D0%B8%D0%BD%D1%85%D1%80%D0%BE%D0%BD%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F)
    1. https://en.wikipedia.org/wiki/Happened-before
    1. https://docs.oracle.com/javase/tutorial/essential/concurrency/index.html
    1. https://www.amazon.com/Java-Concurrency-Practice-Brian-Goetz/dp/0321349601/192-1511873-1398145?ie=UTF8&*Version*=1&*entries*=0
    1. https://habrahabr.ru/company/golovachcourses/blog/256883/
    1. http://ru.stackoverflow.com/questions/1271/%D0%9A%D0%BB%D1%8E%D1%87%D0%B5%D0%B2%D0%BE%D0%B5-%D1%81%D0%BB%D0%BE%D0%B2%D0%BE-volatile-%D0%B2-java
    1. https://ru.wikipedia.org/wiki/%D0%90%D1%82%D0%BE%D0%BC%D0%B0%D1%80%D0%BD%D0%B0%D1%8F_%D0%BE%D0%BF%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D1%8F