Читаем Многопоточное программирование в Java полностью

Как только последний поток вызывает метод await, он прибывает к барьеру, выполняется действие барьера и потоки вызывают метод await второго барьера.

Как только последний поток вызывает метод await, выполняется действие второго барьера и потоки освобождаются.

Синхронизатор Phaser аналогичен синхронизатору CyclicBarrier, за исключением того, что в CyclicBarrier количество участников-потоков фиксировано, а в Phaser новые участники-потоки могут регистрироваться и отменять регистрацию динамически.



В этом примере, мы создаем синхронизатор.



И при создании экземпляра Phaser из основного потока мы передаем 1 в качестве аргумента.

Это эквивалентно вызову метода register из текущего потока.

Мы делаем это, потому что, когда мы создаем три рабочих потока, основной поток является координатором, и поэтому Phaser должен иметь четыре зарегистрированных потока.

Далее создаются три потока, выполняющих задачу, в которую передается синхронизатор.

В этой задаче поток регистрируется для синхронизатора и вызывает метод arriveAndAwaitAdvance, который аналогичен методу await CyclicBarrier и собирает потоки у барьера, включая главный поток.

Как только последний поток вызывает метод arriveAndAwaitAdvance, включая главный поток, фаза завершается.

Отмена регистрации потока для синхронизатора производится методом arriveAndDeregister.

Здесь в первом вызове метод getPhase вернет 0, так как фаза после инициализации равна нулю.

А во втором вызове метод getPhase вернет 1.

Exchanger (обменник) позволяет обменяться данными между двумя потоками в определенной точке работы обоих потоков.



Обмен производится с помощью метода exchange синхронизатора Exchanger, который ожидает, когда другой поток достигнет этой точки обмена, этой точки кода, а затем передает указанный объект другому потоку, получая его объект взамен.



В этом примере создаются два потока, обрабатывающие задачу.



И в этой задаче вызывается метод exchange, который берет значение поля другого потока и присваивает его полю текущего потока.

Параллельные потоки Stream


Ранее мы уже познакомились с программным интерфейсом Stream API, который значительно упрощает работу с коллекциями данных, позволяя отфильтровать, преобразовать и объединить данные без их промежуточного сохранения.



Кроме того, Stream API не модифицирует обрабатываемую коллекцию данных, а позволяет создать на ее основе новую коллекцию данных после обработки.

Напомню, что операторы Stream API делятся на две группы:

Промежуточные операторы, которые обрабатывают поступающие элементы и возвращают стрим.

И терминальные операторы, которые обрабатывают элементы и завершают работу стрима, так что терминальный оператор в цепочке может быть только один.

Обработка коллекции в Stream API не начинается до тех пор, пока не будет вызван терминальный оператор, то есть обработка происходит от терминального оператора к источнику.

И стрим нельзя использовать повторно. Как только вы вызываете любую терминальную операцию, стрим закрывается.

Стрим потоки могут выполняться параллельно, чтобы увеличить производительность обработки большого количества элементов.



Параллельные потоки стрим созданы на основе фреймворка Fork/Join и используют общий пул потоков ForkJoinPool, создаваемый с помощью статического метода ForkJoinPool.commonPool.

Размер общего пула потоков зависит от количества доступных физических ядер процессора.

Под капотом параллельный Stream API обеспечивает работу с потоконебезопасными коллекциями, разбиение коллекции элементов на части, создание потоков и объединение частей вместе.

Потокобезопасность обработки коллекций здесь достигается за счет отсутствия модификации коллекции во время ее обработки.

При использовании параллельного стрима, элементы разбиваются (если это возможно) на несколько групп и обрабатываются в каждом потоке отдельно.

Затем на нужном этапе группы объединяются в одну для предоставления конечного результата.

Чтобы получить параллельный стрим, нужно либо вызвать метод parallelStream вместо метода stream, либо превратить обычный стрим в параллельный, вызвав промежуточный оператор parallel.



Параллельные потоки стрим могут дать прирост производительности в случае большого количества элементов на входе и наличия нескольких ядер процессора. В случае одного ядра их применение бессмыслено.

Если количество элементов небольшое, нужно учесть, что некоторые параллельные стрим операции, такие как reduce и collect, требуют дополнительных вычислений (операций объединения), которые не нужны при последовательном выполнении. Поэтому в случае небольшого количества элементов, последовательный стрим может выполнится быстрее, чем параллельный стрим.

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

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

Перейти на страницу:

Похожие книги

«Ага!» и его секреты
«Ага!» и его секреты

Вы бы не хотели, скажем, изобрести что-то или открыть новый физический закон, а то и сочинить поэму или написать концерт для фортепьяно с оркестром?Не плохо бы, верно? Только как это сделать? Говорят, Шиллер уверял, будто сочинять стихи ему помогает запах гнилых яблок. И потому, принимаясь за работу, всегда клал их в ящик письменного стола. А физик Гельмгольц поступал иначе. Разложив все мысленно по полочкам, он дожидался вечера и медленно поднимался на гору лесной дорогой. Во время такой прогулки приходило нужное решение.Словом, сколько умов, столько способов заставить мозг работать творчески. А нет ли каких-то строго научных правил? Одинаковы ли они для математиков, биологов, инженеров, поэтов, художников? Да и существуют ли такие приемы, или каждый должен полагаться на свои природные способности и капризы вдохновения?Это тем более важно знать, что теперь появились «электронные ньютоны» — машины, специальность которых делать открытия. Но их еще нужно учить.Решающее слово здесь принадлежит биологам: именно они должны давать рецепты инженерам. А биологи и сами знают о том, как мы думаем, далеко не все. Им предстоит еще активнее исследовать лабораторию нашего мышления.О том, как ведутся эти исследования, как постепенно «умнеют» машины, как они учатся и как их учат, — словом, о новой науке эвристике рассказывает эта книга.

Елена Викторовна Сапарина

Зарубежная компьютерная, околокомпьютерная литература
Создание трилогии BioShock. От Восторга до Колумбии
Создание трилогии BioShock. От Восторга до Колумбии

Всего за три игры сага BioShock заняла особое место в сердцах игроков. Она может похвастаться проработанными и совершенно уникальными персонажами и мирами. Действие первых двух частей происходит в подводном городе Восторг, где игрок погружается в стиль ар-деко и атмосферу 1950-х годов. Третья часть, BioShock Infinite, переносит вас в 1912 год и приглашает исследовать небесный город Колумбия в сеттинге стимпанка.В книге вас ждут:[ul]рассуждение об источниках вдохновения создателя серии Кена Левина;исследование уникального геймплея и механик;подробности разработки игр франшизы от идеи до выпуска;глубокий анализ сюжета, тем и персонажей каждой части.[/ul]Авторы отдают дань уважения популярной серии игр, которая, несмотря на короткую историю, уже получила признание критиков.В формате PDF A4 сохранен издательский макет книги.

Мехди Эль Канафи , Николя Курсье , Рафаэль Люка

Зарубежная компьютерная, околокомпьютерная литература