Видны ли все побочные эффекты задач executor после invokeAll? - PullRequest
2 голосов
/ 14 сентября 2011

Если я отправляю некоторые задачи на Executor, используя invokeAll, я гарантирую, что представленный поток увидит все побочные эффекты выполнения задач, даже если я не вызываю get() для каждого из возвращенных Future s

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

Точнее, все ли действия в теле Callable, представленные исполнителю , происходят до возврата из вызова invokeAll()?

Раздражает бесполезный вызов get() для каждого будущего, когда фактически возвращается тип Void и не выдается никаких исключений - вся работа в этом случае происходит как побочные эффекты.

Ответы [ 2 ]

1 голос
/ 14 сентября 2011

Из документации ExecutorService :

Действия в потоке перед отправкой задачи Runnable или Callable в ExecutorService происходят до того, как какие-либо действия, предпринятые этой задачейчто, в свою очередь, происходит до того, как результат будет получен через Future.get ().

Когда я это читаю, при отправке задачи возникает барьер памяти, поэтому потенциально выВам нужно вызвать get() для последней задачи в вашем списке, но не другие.

Однако , так как вызов get() - единственный способ определить, является ли задачавыполненный или брошенный, я бы все равно вызывал его на каждом Future, независимо от гарантий памяти.

1 голос
/ 14 сентября 2011

Если invokeAny() обещает, что при возврате invokeAny() никакие задачи еще не выполняются, это будет иметь место: все побочные эффекты видны.

Чтобы invokeAny() знал, что все задачи выполнены, он должен быть синхронизирован с этими потоками, что означает, что возврат функций происходит после завершения задач (и всего, что происходит в задаче),Однако API ExecutorSerive и Future.cancel () явно не говорит, что происходит, когда вы отменяете запущенную задачу (в частности: cancel() будет ждать с возвратом, пока задачи не перестанут выполняться. Тот факт, что после вызоваcancel(), isDone() должен возвращать true, подразумевает, что cancel() не вернется, пока задача фактически не завершится.

Еще одна вещь, на которую следует обратить внимание, это то, что вы не будете знать, если задачакогда-либо началось выполнение при использовании invokeAny() без проверки объектов Future.

...