- 
      
- 
        Save andreikastsiuk/e6e521e41919e05a94162f4668f632e0 to your computer and use it in GitHub Desktop. 
Revisions
- 
        vchernogorov revised this gist Apr 22, 2017 . 1 changed file with 3 additions and 1 deletion.There are no files selected for viewingThis file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -4,4 +4,6 @@ ### Содержание: - [Понятия многопоточности](#file-concurrency-concepts-md) - [Java инструменты многопоточности](#file-java-concurrency-tools-md) - [`Thread` объект](#file-concurrency-thread-object-md) 
- 
        vchernogorov revised this gist Apr 22, 2017 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewingThis file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -4,4 +4,4 @@ ### Содержание: - [Понятия многопоточности](#file-concurrency-concepts-md) 
- 
        vchernogorov revised this gist Apr 22, 2017 . 5 changed files with 62 additions and 63 deletions.There are no files selected for viewingThis file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal 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) This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal 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 This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,6 +1,4 @@ # Понятия многопоточности 1. **Monitor** - высокоуровневый механизм взаимодействия и синхронизации процессов, обеспечивающий доступ к неразделяемым ресурсам. - При многозадачности, основанной на мониторах, компилятор или интерпретатор прозрачно для программиста вставляет код блокировки-разблокировки в оформленные соответствующим образом процедуры, избавляя программиста от явного обращения к примитивам синхронизации. @@ -69,63 +67,3 @@ 20. **Critical section** - участок кода, в котором производится доступ к общему ресурсу, который не должен быть одновременно использован более чем одним потоком. - Мьютекс является процедурой входа/выхода из критической секции. This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal 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()`** - указывает планировщику, что текущий поток закончил свое выполнение и готов перейти в пользование процессора. Планировщик однаком может игнорировать это указание. - Использование данного метода редко является уместным. Он может использоваться для дебага или тестирования. This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal 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` методами и блоками. 
- 
        vchernogorov revised this gist Apr 16, 2017 . 1 changed file with 33 additions and 33 deletions.There are no files selected for viewingThis file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -16,71 +16,71 @@ 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** - участок кода, в котором производится доступ к общему ресурсу, который не должен быть одновременно использован более чем одним потоком. - Мьютекс является процедурой входа/выхода из критической секции. --- ### 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`, который должен содержать код, который будет выполняться в потоке. @@ -93,28 +93,28 @@ 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()`** - указывает планировщику, что текущий поток закончил свое выполнение и готов перейти в пользование процессора. Планировщик однаком может игнорировать это указание. - Использование данного метода редко является уместным. Он может использоваться для дебага или тестирования. --- 
- 
        vchernogorov revised this gist Apr 16, 2017 . 1 changed file with 5 additions and 5 deletions.There are no files selected for viewingThis file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -3,15 +3,15 @@ ### 1. Общее 1. **Monitor** - высокоуровневый механизм взаимодействия и синхронизации процессов, обеспечивающий доступ к неразделяемым ресурсам. - При многозадачности, основанной на мониторах, компилятор или интерпретатор прозрачно для программиста вставляет код блокировки-разблокировки в оформленные соответствующим образом процедуры, избавляя программиста от явного обращения к примитивам синхронизации. 2. **Semaphore** - семафор, самый простой тип блокировки, ограничивает количество потоков, которые могут войти в заданный участок кода. - Семафоры используются для синхронизации и защиты передачи данных через разделяемую память, а также для синхронизации работы процессов и потоков. 3. **Mutex** - двоичный простейший семафор, который может находиться в одном из двух состояний: отмеченном или неотмеченном. Он отличается от семафора тем, что только владеющий им поток может его освободить, т.е. перевести в отмеченное состояние. - Задача мьютекса — защита объекта от доступа к нему других потоков, отличных от того, который завладел мьютексом. - В каждый конкретный момент только один поток может владеть объектом, защищённым мьютексом. - Если другому потоку будет нужен доступ к переменной, защищённой мьютексом, то этот поток блокируется до тех пор, пока мьютекс не будет освобождён. 4. **Reentrant mutex** - мьютекс, который может быть залочен несколько раз одиним и тем же процессом/потоком без создания взаимной блокировки. 
- 
        vchernogorov revised this gist Apr 16, 2017 . 1 changed file with 38 additions and 38 deletions.There are no files selected for viewingThis file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -5,69 +5,69 @@ 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** - участок кода, в котором производится доступ к общему ресурсу, который не должен быть одновременно использован более чем одним потоком. - Мьютекс является процедурой входа/выхода из критической секции. --- @@ -77,55 +77,55 @@ 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 
- 
        vchernogorov created this gist Apr 16, 2017 .There are no files selected for viewingThis file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal 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