Как ограничить поток для запуска последовательно и запретить его параллельную работу?
У меня есть метод, который возвращает поток, который генерируется из пользовательского сплитератора; Сплитератор не является безопасным протектором. Поскольку сплитератор не является безопасным протектором и поддерживает состояние, я хочу, чтобы он не работал параллельно. Есть ли способ предотвратить параллельный запуск возвращаемого потока?
Мне не удалось найти какую-либо документацию или примеры, которые делают это. Я нашел sequential()
метод на BaseStream
класс, но это не мешает пользователю тогда звонить parallel()
чтобы получить параллельный поток.
2 ответа
Параллельные потоковые вызовы trySplit()
метод вашего сплитератора, чтобы разделить вашу задачу на несколько частей. Возвращение абсолютно законно null
от trySplit()
говоря, что "я отказываюсь разделять". В этом случае поток, созданный вашим сплитератором, будет выполняться последовательно, даже если .parallel()
был явно назван.
Однако в целом вы можете обеспечить как минимум ограниченный параллелизм, расширяющий AbstractSpliterator
учебный класс. Это обеспечивает по умолчанию trySplit()
реализация, которая читает некоторые элементы ввода, вызывающие ваш tryAdvance()
метод, сохраняя их в массив и возвращая сплитератор в этом массиве, так что эта часть может обрабатываться отдельно и полностью независимо от вашего сплитератора. Это распараллеливание "бедняков", но оно все же может улучшить скорость, если операции в нисходящем потоке требуют много времени.
В заключение отметим, что в большинстве простых случаев реализация Spliterator не должна быть поточно-ориентированной. Если вы предоставите свой собственный эффективный trySplit()
Реализация гарантирует, что оригинальный сплитератор и вновь созданный сплитератор будут обрабатываться совершенно независимо. Поэтому, если вы не изменяете общее состояние в префиксе и суффиксе сплитератора после разделения, вам не следует заботиться о безопасности потоков.
По умолчанию потоки являются синхронными, поэтому вопрос не имеет значения, правильно ли вы документируете свою библиотеку. Пользователь несет ответственность за то, чтобы используемая им библиотека была поточно-ориентированной. Просто сделай очевидным, что это не так.
Существует способ проверить поток, если вы можете отправить идентификатор потока на стороне сервера и получить его на стороне клиента через API:
Thread.currentThread().getId()
И сравните его с вашим идентификатором темы, когда вы его получите. Бросить Exception
с явным сообщением об ошибке "Не поточно-безопасно!" когда они разные.