Как ограничить поток для запуска последовательно и запретить его параллельную работу?

У меня есть метод, который возвращает поток, который генерируется из пользовательского сплитератора; Сплитератор не является безопасным протектором. Поскольку сплитератор не является безопасным протектором и поддерживает состояние, я хочу, чтобы он не работал параллельно. Есть ли способ предотвратить параллельный запуск возвращаемого потока?

Мне не удалось найти какую-либо документацию или примеры, которые делают это. Я нашел sequential() метод на BaseStream класс, но это не мешает пользователю тогда звонить parallel() чтобы получить параллельный поток.

2 ответа

Решение

Параллельные потоковые вызовы trySplit() метод вашего сплитератора, чтобы разделить вашу задачу на несколько частей. Возвращение абсолютно законно null от trySplit() говоря, что "я отказываюсь разделять". В этом случае поток, созданный вашим сплитератором, будет выполняться последовательно, даже если .parallel() был явно назван.

Однако в целом вы можете обеспечить как минимум ограниченный параллелизм, расширяющий AbstractSpliterator учебный класс. Это обеспечивает по умолчанию trySplit() реализация, которая читает некоторые элементы ввода, вызывающие ваш tryAdvance() метод, сохраняя их в массив и возвращая сплитератор в этом массиве, так что эта часть может обрабатываться отдельно и полностью независимо от вашего сплитератора. Это распараллеливание "бедняков", но оно все же может улучшить скорость, если операции в нисходящем потоке требуют много времени.

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

По умолчанию потоки являются синхронными, поэтому вопрос не имеет значения, правильно ли вы документируете свою библиотеку. Пользователь несет ответственность за то, чтобы используемая им библиотека была поточно-ориентированной. Просто сделай очевидным, что это не так.

Существует способ проверить поток, если вы можете отправить идентификатор потока на стороне сервера и получить его на стороне клиента через API:

Thread.currentThread().getId()

И сравните его с вашим идентификатором темы, когда вы его получите. Бросить Exception с явным сообщением об ошибке "Не поточно-безопасно!" когда они разные.

Другие вопросы по тегам