Гарантирует ли спецификация, что операции с последовательными потоками Java должны оставаться в текущем потоке? - PullRequest
0 голосов
/ 23 мая 2018

Гарантирует ли спецификация, что все операции на последовательных Java-потоках выполняются в текущем потоке?(За исключением «forEach» и «forEachOrdered»)

Я явно запрашиваю спецификацию, а не то, что делает текущая реализация.Я сам могу посмотреть текущую реализацию и не нужно беспокоить вас этим.Но реализация может измениться, и есть другие реализации.

Я спрашиваю из-за ThreadLocals: я использую Framework, который использует ThreadLocals для внутреннего использования.Даже простой вызов, такой как company.getName (), в конечном итоге использует ThreadLocal.Я не могу изменить, как эта структура разработана.По крайней мере, не в разумный промежуток времени.

Спецификация кажется здесь запутанной.Документация пакета "java.util.stream" гласит:

Если поведенческие параметры действительно имеют побочные эффекты, если явно не указано, нет никаких гарантий относительновидимость этих побочных эффектов для других потоков, и нет никаких гарантий того, что различные операции над «одним и тем же» элементом в одном и том же потоковом конвейере выполняются в одном потоке .

...

Даже когда конвейер ограничен для получения результата, который соответствует порядку встречи с источником потока (например, IntStream.range (0,5) .parallel (). Map (x ->x * 2) .toArray () должен выдавать [0, 2, 4, 6, 8]), не даются гарантии относительно порядка, в котором функция mapper применяется к отдельным элементам, или в каком потоке выполняется любой поведенческий параметр для данного элемента.

Я бы интерпретировал это как: каждая операция в потоке может происходить в другом потоке.Но документация "forEach" и "forEachOrdered" прямо заявляет:

Для любого данного элемента действие может быть выполнено в любое время и в любом потоке, выбранном библиотекой.

Этот оператор был бы излишним, если бы каждая потоковая операция могла происходить в неопределенном потоке.Следовательно, верно ли обратное: все операции над последовательным потоком гарантированно выполняются в текущем потоке, за исключением «forEach» и «forEachOrdered»?

Я гуглил авторитетный ответ о комбинации "Java "," Stream "и" ThreadLocal ", но ничего не нашел.Закрытие было ответом Брайана Гетца на связанный вопрос здесь, в Переполнении стека, но речь идет о порядке, а не о потоке, и речь идет только о «forEach», а не о других методах потока: Учитывает ли Stream.forEach порядок встречи последовательных потоков?

1 Ответ

0 голосов
/ 23 мая 2018

Я думаю, что ответ, который вы ищете, не так хорошо определен, так как будет зависеть от потребителя и / или сплитератора и их характеристик:

Перед прочтением основной цитаты:

https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html#stream

default Stream stream () Возвращает последовательный поток с этой коллекцией в качестве источника.Этот метод должен быть переопределен, когда метод spliterator () не может вернуть сплитератор IMMUTABLE, CONCURRENT или позднего связывания.(Подробности см. В spliterator ().)

https://docs.oracle.com/javase/8/docs/api/java/util/Spliterator.html#binding

Несмотря на очевидную полезность параллельных алгоритмов, сплитераторы не должны быть поточно-ориентированными;вместо этого реализации параллельных алгоритмов с использованием сплитераторов должны гарантировать, что сплитератор используется только одним потоком за раз.Как правило, этого легко достичь с помощью последовательного ограничения потока, что часто является естественным следствием типичных параллельных алгоритмов, работающих с помощью рекурсивной декомпозиции.Поток, вызывающий trySplit (), может передать возвращенный Spliterator другому потоку, который, в свою очередь, может пересечь или дополнительно разделить этот Spliterator.Поведение разделения и обхода не определено, если два или более потоков работают одновременно на одном и том же разделителе.Если исходный поток передает сплитератор другому потоку для обработки, лучше всего, чтобы эта эстафетная передача произошла до того, как какие-либо элементы будут использованы с помощью tryAdvance (), поскольку некоторые гарантии (например, точность оценки SsED () для сплитераторов SIZED) действительныдо начала обхода.

Сплитераторы и потребители имеют свои характеристики, и это определит гарантию.Давайте предположим, что вы работаете в стриме.Поскольку предполагается, что сплитераторы не являются потокобезопасными и должны обрабатывать элементы для других сплитераторов, которые могут быть в другом потоке, были последовательными или нет, гарантия здесь нулевая.Однако, если не произойдет разделения, кавычки приведут к следующему: при одном сплитераторе операции останутся в том же потоке, любое событие, которое приведет к разделению, приведет к тому, что допущение будет нулевым, но в противном случае будет истинным

...