Разъяснение java Fork/Join об использовании стека

Я читал о реализации фреймворка Fork/Join, представленного в Java 7, и просто хотел проверить, понимаю ли я, как работает магия.

Насколько я понимаю, когда поток разветвляется, он создает в своей очереди подзадачи (, которые другой поток может или не может украсть ). Когда поток пытается «присоединиться», он фактически проверяет свою очередь на наличие существующих задач, а затем рекурсивно выполняет их, что означает, что для любой операции «присоединения» -2 кадра будут добавлены в стек вызовов потока (один для соединение и один для нового вызова задачи ).

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

Я прав или они нашли какой-то классный способ предотвратить это?

РЕДАКТИРОВАТЬ

Вот сценарий, который поможет прояснить вопрос :Скажем (для простоты ), что у нас есть только один поток в пуле forkjoin. В какой-то момент времени -поток разветвляется, а затем вызывает соединение. Находясь в методе соединения, поток обнаруживает, что он может выполнять разветвленную задачу (, как он нашел в своей очереди ), поэтому он вызывает следующую задачу. Эта задача, в свою очередь, разветвляется, а затем вызывает соединение -, поэтому при выполнении метода соединения поток найдет разветвленную задачу в своей очереди (, как и раньше ), и вызовет ее. на этом этапе стек вызовов будет содержать как минимум кадры для двух объединений и двух задач.

как вы можете видеть, структура fork join трансформировалась в простую рекурсию. Поскольку java не поддерживает оптимизацию хвостовых вызовов -, каждая рекурсия в java может вызвать StackOverflowError, если она идет достаточно глубоко.

Мой вопрос: -нашел ли разработчик инфраструктуры fork/join какой-нибудь классный способ предотвратить эту ситуацию.

18
задан bennyl 5 July 2012 в 22:17
поделиться