ForkJoinPool zatrzymuje się podczas invokeAll / join

Próbuję użyć aForkJoinPool aby zrównoważyć obliczenia intensywne procesora. Moje rozumienie ForkJoinPool polega na tym, że nadal działa tak długo, jak długo dostępne jest dowolne zadanie do wykonania. Niestety, często obserwowałem wątki pracujące na biegu jałowym / czekającym, a zatem nie wszystkie procesory są zajęte. Czasami nawet obserwowałem dodatkowe wątki robocze.

Nie spodziewałem się tego, czego starałem się używaćbez blokowania zadania. Moja obserwacja jest bardzo podobna do obserwacjiForkJoinPool wydaje się marnować wątek. Po wielu debugowaniu w ForkJoinPool mam zgadnięcie:

Użyłem invokeAll () do dystrybucji pracy nad listą podzadań. Po zakończeniu invokeAll () w celu wykonania pierwszego zadania zaczyna się dołączać do pozostałych. Działa to dobrze, dopóki następne zadanie do dołączenia nie znajdzie się na szczycie kolejki wykonawczej. Niestety przesłałem dodatkowe zadania asynchronicznie, nie dołączając do nich. Spodziewałem się, że framework ForkJoin będzie kontynuował wykonywanie tych zadań w pierwszej kolejności, a następnie powróci do łączenia pozostałych zadań.

Ale wydaje się, że nie działa w ten sposób. Zamiast tego wątek roboczy zostaje zablokowany wywołując wait (), dopóki zadanie czekające nie zostanie przygotowane (prawdopodobnie wykonywane przez inny wątek roboczy). Nie weryfikowałem tego, ale wydaje się, że jest to ogólna wada wywoływania join ().

ForkJoinPool zapewniaasyncMode, ale jest to parametr globalny i nie można go używać do indywidualnych zgłoszeń. Ale lubię, aby moje asynchronicznie rozwidlone zadania były wykonywane wkrótce.

Dlaczego więc ForkJoinTask.doJoin () nie wykonuje po prostu żadnego dostępnego zadania na wierzchu swojej kolejki, dopóki nie będzie gotowe (wykonane samodzielnie lub skradzione przez innych)?

questionAnswers(3)

yourAnswerToTheQuestion