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

При таком подходе ExecutorService сначала прекратит принимать новые задачи, подождет определенный период времени для завершения всех задач.

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

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



Вместо использования объекта Runnable, так как использование Runnable ограничено тем, что задачи не могут вернуть результат, для создания задачи можно использовать объект Callable, который позволяет задаче вернуть результат.



Если в Runnable мы определяем метод run, то в Callable, мы определяем метод call.

Метод submit помещает задачу в очередь для выполнения потоком.

Однако он не знает, когда будет получен результат этой задачи.

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

Метод ExecutorService.submit немедленно возвращает объект Future.

После того, как вы получили Future, вы можете выполнять другие задачи параллельно во время выполнения поставленной задачи, а затем использовать метод future.get для получения результата.

Обратите внимание, метод get устанавливает блокировку текущего потока до тех пор, пока не завершится выполнение задачи.

Future также предоставляет метод isDone для проверки того, завершена задача или нет.



Если прерывается поток, выполняющий вычисление, метод генерирует исключение InterruptedException.

Когда вычисление задачи завершается, метод get немедленно возвращает управление.

Вы можете отменить Future, используя метод Future.cancel, который пытается отменить выполнение задачи и возвращает true, если она отменена успешно, иначе метод возвращает false.



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

Вы можете использовать метод isCancelled, чтобы проверить задача отменена или нет.

Кроме того, после отмены задачи, метод isDone всегда будет возвращать true.

Метод future.get блокирует и ждет завершения задачи.

Если, вы вызываете удаленную службу в задаче, а удаленная служба отключена, то future.get заблокирует приложение навсегда.

Чтобы это предотвратить, вы можете добавить в метод get время ожидания.



Также, как и с объектом Runnable, с помощью объекта Callable, вы можете одновременно создать сразу несколько задач и отправить их на выполнение.

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



Во-вторых, мы используем метод invokeAll, чтобы выполнить несколько задач, передавая коллекцию объектов Callable.

Метод invokeAll возвращает список объектов Future.

Метод invokeAll ожидает, пока все результаты не будут вычислены до их возврата. То есть метод invokeAll возвращает список объектов Future, для которых isDone true.

В отличие от метода submit, который возвращает сразу, метод invokeAll ожидает завершения задач.

Так как метод invokeAll возвращает коллекцию, ее можно обработать с помощью Stream API.



В отличие от метода invokeAll, метод invokeAny передает на выполнение список задач и ожидает выполнение любой из них, то есть наиболее быстрой.



Для выполнения задачи либо периодически, либо после указанной задержки, можно использовать ScheduledExecutorService.



Здесь метод schedule принимает объект Runnable, задержку и единицу задержки, и определяет выполнение задачи через 5 секунд с момента отправки.

Метод scheduleAtFixedRate принимает объект Runnable, начальную задержку, период выполнения и единицу времени, и запускает выполнение заданной задачи после указанной задержки и затем периодически выполняет ее с указанным интервалом.

Имейте в виду, что scheduleAtFixedRate не учитывает фактическую продолжительность задачи. Поэтому, если вы укажете период в одну секунду, но для выполнения задачи потребуется 2 секунды, тогда пул потоков начнет быстро перегружаться.

Поэтому для периодического запуска задачи лучше использовать метод scheduleWithFixedDelay.

Разница заключается в том, что период ожидания применяется от конца задачи до начала следующей задачи.

В этом примере задача выполняется периодически с фиксированной задержкой в одну секунду между окончанием выполнения и началом следующего выполнения.

Чтобы удалить задачу без остановки ScheduledExecutorService, можно использовать результат ScheduledFuture, возвращаемый методами интерфейса ScheduledExecutorService, и применить к этому результату метод cancel.



Для возврата результата, в метод schedule можно передать не объект Runnable, а объект Callable, и применить к результату ScheduledFuture метод get, так как ScheduledFuture расширяет уже знакомый нам интерфейс Future.



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

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

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

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

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

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

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

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

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