Где официальная документация говорит, что в параллельных потоках Java используются fork/join?

Здесь мое понимание Потоковая инфраструктура Java 8:

  • Что-то создает источник Stream
  • Реализация отвечает за предоставление метода BaseStream # parallel(), который по очереди возвращает поток, который может выполнять его параллельно.

В то время как кто-то уже нашел способ использовать собственный пул потоков с параллельными каскадами Stream, я не могу на всю жизнь найти какое-либо упоминание в Java 8 API, что реализация Java по параллельному потоку Java по умолчанию будет использовать ForkJoinPool # commonPool(). (Коллекция # parallelStream(), методы в StreamSupport и другие возможные источники параллельных потоков в API, о которых я не знаю).

Только лакомые кусочки, которые я мог отследить от результатов поиска, были следующими:


Итак, мой вопрос:

Где сказано, что ForkJoinPool # commonPool() используется для параллельных операций над потоками, которые получены из Java 8 API?

Ответ 1

W.r.t. где документировано, что параллельные потоки Java 8 используют FJ Framework?

Afaik (Java 1.8u5) в JavaDoc параллельных потоков не упоминается, что используется обычный ForkJoinPool.

Но это упоминается в документации ForkJoin внизу http://docs.oracle.com/javase/tutorial/essential/concurrency/forkjoin.html

W.r.t. заменяя пул потоков

Я понимаю, что вы можете использовать собственный ForkJoinPool (вместо обычного) - см. Пользовательский пул потоков в параллельном потоке Java 8 - но не пользовательский ThreadPool, который отличается от реализации ForkJoin (у меня есть открытый вопрос: Как (глобально) заменить общий пул потоков потока параллельных потоков Java?)

W.r.t. заменяя потоки api

Вы можете проверить https://github.com/nurkiewicz/LazySeq, который является более реалистичной реализацией потоков Scala - очень приятный, очень интересный

PS (w.r.t. ForkJoin и потоки)

Если вам интересно, я хотел бы отметить, что я наткнулся на некоторые проблемы с использованием пула FJ, см., например,

Ответ 2

Для того, что стоит, Java 8 в Action имеет главу о параллельной обработке и производительности данных (глава 7). В нем говорится:

"... интерфейс Stream дает вам возможность выполнить параллельные операции по набору данных без особых усилий".

"... вы увидите, как Java может сделать это волшебство, или, больше практически, как параллельные потоки работают под капотом, используя fork/join, введенные в Java 7.

В разделе 7.1 также есть небольшая заметка:

"Параллельные потоки внутренне используют ForkJoinPool по умолчанию... который по умолчанию имеет столько потоков, сколько у вас есть процессоры, возвращенные Runtime.getRuntime().availableProcessors()."

"вы можете изменить размер этого пула, используя системное свойство java.util.concurrent.ForkJoinPool.common.parallelism, как в следующем примере:"

System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism","12");

Как упоминалось в комментариях и других ответах, это не означает, что он всегда будет использовать fork/join.

Ответ 3

Вы можете проверить исходный код операций терминала на GrepCode. Например, давайте взглянем на ForEachOp. Как вы можете видеть, метод compareParallel ForEachOp создает и вызывает объект ForEachTask, полученный из CountedCompleter, полученный из ForkJoinTask.