Concurrent Collections — набор коллекций, более эффективно работающие в многопоточной среде нежели стандартные универсальные коллекции из java.util пакета. Вместо базового враппера Collections.synchronizedList с блокированием доступа ко всей коллекции используются блокировки по сегментам данных или же оптимизируется работа для параллельного чтения данных по wait-free алгоритмам.
Queues — неблокирующие и блокирующие очереди с поддержкой многопоточности. Неблокирующие очереди заточены на скорость и работу без блокирования потоков. Блокирующие очереди используются, когда нужно «притормозить» потоки «Producer» или «Consumer», если не выполнены какие-либо условия, например, очередь пуста или перепонена, или же нет свободного «Consumer»'a.
Synchronizers — вспомогательные утилиты для синхронизации потоков. Представляют собой мощное оружие в «параллельных» вычислениях.
Executors — содержит в себе отличные фрейморки для создания пулов потоков, планирования работы асинхронных задач с получением результатов.
Locks — представляет собой альтернативные и более гибкие механизмы синхронизации потоков по сравнению с базовыми synchronized, wait, notify, notifyAll.
Atomics — классы с поддержкой атомарных операций над примитивами и ссылками.
8. BlockingQueue
Интерфейс BlockingQueue является очередью
(Queue), т.е. его элементы хранятся в порядке
«первый пришел, первый вышел» (FIFO – first in, first
out). Элементы, вставленные в коллекцию в
определенном порядке, будут извлечены из нее в
том же самом порядке. Также интерфейс
гарантирует, что любая попытка извлечь элемент из
пустой очереди заблокирует вызывающий поток до
тех пор, пока в коллекции не появится элемент,
который можно извлечь. Аналогично, любая попытка
вставить элемент в заполненную очередь
заблокирует вызывающий поток, пока в коллекции не
освободится место для нового элемента.
9.
10.
11.
12. Семафор используется для
обмена сигналами между
потоками, или же для охраны
критической секции. Их также
можно использовать и вместо
локов.
13.
14. CountDownLatch
Позволяет одному или нескольким потокам ожидать
до тех пор, пока не завершится определенное
количество операций, выполняющих в других
потоках.
Реализует синхронизационную модель «щеколды»
— создается щеколда (с натуральным числом в
качестве параметра-счетчика), которая постепенно
вынимается с выполнение каких-то операций (как
только такая операция выпонена, вызывается
метод void countDown(), уменьшающий счетчик).
Потоки, которые должны подождать конца
выполнения данной цепочки операций, вызывают
метод await() и блокируются. Как только щеколда
будет вынута (счетчик упадет до нуля), все
ожидающие потоки разблокируются и продолжают
выполнение.
15.
16. CyclicBarrier
— реализует синхронизационную модель
«щеколды» — создается щеколда (с
натуральным числом в качестве
параметра-счетчика), которая постепенно
вынимается с выполнение каких-то
операций (как только такая операция
выпонена, вызывается метод void
countDown(), уменьшающий счетчик).
Потоки, которые должны подождать конца
выполнения данной цепочки операций,
вызывают метод await() и блокируются. Как
только щеколда будет вынута (счетчик
упадет до нуля), все ожидающие потоки
разблокируются и продолжают
выполнение.
17. Приведите наиболее
существенное отличие между
CountDownLatch и Barrier.
Barrier накапливает потоке в точке вызова
await() пока их количество не превысит
заданное. CountDownLatch ждет пока
количество вызовов countDown() не превысит
нужное, и тогда разблокирует await().
18. FutureResult (будущий
результат)
Иногда вы хотите запустить процесс асинхронно, в
надежде, что результаты этого процесса будут
доступны позже, когда они вам понадобятся.
Вспомогательный класс FutureResult упрощает эту
задачу. FutureResult изображает задачу, которой
может потребоваться некоторое время на
выполнение, и которая может выполняться в другом
потоке, а объект FutureResult служит хендлом к
этому процессу выполнения. Через него вы можете
выяснить, завершилась ли задача, подождать ее
завершения и получить ее результат. FutureResult
может быть объединен с Executor; вы можете
создать FutureResult и поставить его в очередь к
обработчику, сохраняя ссылку на FutureResult.
19. обработчик (Executor)
Util.concurrent определяет интерфейс
Executor, для асинхронной обработки
Runnable-работ, а также определяет
несколько реализаций обработчика
Executor, которые предлагают различные
характеристики планирования. Постановка
задачи в очередь к обработчику делается
довольно просто:
Executor executor = new QueuedExecutor();
...
Runnable runnable = ... ;
executor.execute(runnable);
20. ExecutorService
Интерфейс, который описывает
сервис для запуска Runnable или
Callable задач. Методы submit на
вход принимают задачу в виде
Callable или Runnable, а в качестве
возвращаемого значения идет
Future, через который можно
получить результат.
21. java.util.concurrent.locks
ReenterantLock — двоичный семафор с возможностью
многократного захвата одним потоком.
void lock() захватывает семафор для текущего потока
void unlock() освобождает семафор, захваченный текущим
потоком
Condition newCondition() — возвращает объект-условие,
связанный с данным семафором. Можно использовать это
условие для блокировки потоков до его наступления. Поток
блокируется вызовом await() у объекта-события и освобождается,
когда у того же события будет вызван метод signal()
(освобождает только один поток) или signalAll() (освобождает все
блокированные потоки).
22. java.util.concurrent.atomic
В пакет java.util.concurrent.atomic
входят 9 видов атомарных
переменных (AtomicInteger;
AtomicLong; AtomicReference;
AtomicBoolean; формы для массивов
атомарных целых чисел; длинные
(long); ссылки; а также атомарные с
пометкой Класс эталона (reference),
которые атомарно обновляют две
величины).
23. AtomicInteger atomicInteger = new
AtomicInteger(123);
int expectedValue = 123;
int newValue = 234;
atomicInteger.compareAndSet(expectedValue,
newValue);
System.out.println(atomicInteger.getAndAdd(10));
System.out.println(atomicInteger.addAndGet(10));