Я прочитал о реализации структуры Fork/Join, которая была представлена на Java 7, и я просто хотел проверить, что я понимаю, как работает магия.java Fork/Объяснить использование стека
Как я понимаю, когда поток вилки создает в своей очереди подзадачи (какой другой поток может или не может украсть). Когда поток пытается «присоединиться», он фактически проверяет свою очередь на существующие задачи, а затем рекурсивно выполняет их, что означает, что для любой операции «join» - 2 кадра будут добавлены в стек вызовов потока (один для соединения и один для нового принятого вызова задачи).
Как я знаю, JVM не поддерживает оптимизацию хвостовых вызовов (которая может служить в этой ситуации для удаления кадра стека метода соединения) Я считаю, что при выполнении сложной операции с большим количеством вилок и объединений поток может бросать a StackOverflowError
.
Я прав, или они нашли какой-нибудь классный способ предотвратить это?
EDIT
Вот сценарий, чтобы помочь уточняющий вопрос: Say (для простоты), что у нас есть только один поток в forkjoin бассейне. В некоторый момент времени - вилки потоков, а затем звонки соединяются. В то время как в методе соединения поток обнаруживает, что он может выполнить разветвленную задачу (как она найдена в ее очереди), поэтому она вызывает следующую задачу. Эта задача, в свою очередь, вилки, а затем вызывает join - поэтому при выполнении метода соединения поток найдет разветвленную задачу в своей очереди (как и раньше) и вызовет ее. на этом этапе стек вызовов будет содержать как минимум фреймы для двух объединений и две задачи.
, поскольку вы можете видеть, что каркас преобразования fork преобразован в обычную рекурсию. Поскольку java не поддерживает оптимизацию хвостового вызова - каждая рекурсия в java может вызвать StackOverflowError
, если она будет достаточно глубокой.
Мой вопрос - сделал реализатор инфраструктуры fork/join найти какой-нибудь классный способ предотвратить эту ситуацию.
@assylias - уверенный, если вы можете сэкономить очки :) – bennyl