Поток SecureRandom выдает исключения с несколькими потокамиJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Поток SecureRandom выдает исключения с несколькими потоками

Сообщение Anonymous »

Я пытаюсь генерировать случайные значения с помощью SecureRandom, в частности его поддержки потоков. В идеале значения должны генерироваться постоянно, чтобы поток мог быть бесконечным:

Код: Выделить всё

SecureRandom secureRandom = new SecureRandom();
Iterator idIterator = secureRandom.ints().distinct().iterator();
В документации указано, что "

Код: Выделить всё

SecureRandomОбъекты 
безопасны для использования несколькими параллельными потоками." Однако, когда несколько потоков извлекают следующее значение из итератора, я получаю ошибку (по крайней мере) в одном из потоков, которая, по-видимому, связана с состояние гонки:

Код: Выделить всё

Thread t1 = new Thread(() -> idIterator.next());
Thread t2 = new Thread(() -> idIterator.next());
t1.start();
t2.start();

Код: Выделить всё

Exception in thread "Thread-1" java.lang.IllegalStateException: source already consumed or closed
at java.base/java.util.stream.AbstractPipeline.sourceSpliterator(AbstractPipeline.java:409)
at java.base/java.util.stream.AbstractPipeline.lambda$spliterator$0(AbstractPipeline.java:367)
at java.base/java.util.stream.StreamSpliterators$AbstractWrappingSpliterator.init(StreamSpliterators.java:142)
at java.base/java.util.stream.StreamSpliterators$AbstractWrappingSpliterator.doAdvance(StreamSpliterators.java:157)
at java.base/java.util.stream.StreamSpliterators$IntWrappingSpliterator.tryAdvance(StreamSpliterators.java:358)
at java.base/java.util.Spliterators$2Adapter.hasNext(Spliterators.java:726)
at java.base/java.util.Spliterators$2Adapter.nextInt(Spliterators.java:732)
at java.base/java.util.PrimitiveIterator$OfInt.next(PrimitiveIterator.java:128)
at java.base/java.util.PrimitiveIterator$OfInt.next(PrimitiveIterator.java:86)
at example.Example.foo(Example.java:39)
Когда я запускаю код несколько раз, я иногда получаю исключение другого типа (

Код: Выделить всё

NullPointerException
).
Поведение будет таким же, если я ограничу поток и удалю операцию Different():

Код: Выделить всё

secureRandom.ints().limit(100).iterator();
РЕДАКТИРОВАТЬ:
С другой стороны, если я не буду использовать поток и просто вызову SecureRandom.nextInt() из каждого потока, не наблюдается ожидаемого состояния гонки.

Код: Выделить всё

Thread t1 = new Thread(() -> secureRandom.nextInt());
Thread t2 = new Thread(() -> secureRandom.nextInt());
t1.start();
t2.start(); // code is thread-safe
Мне интересно, почему итератор меняет поведение? Тем более, что в документации Java метода ints() указано, что "псевдослучайное значение int генерируется так, как будто оно является результатом вызова метода nextInt()".
P.S.: Конечно, я могу решить эту проблему, но синхронизируя потоки, получающие следующее значение.

Подробнее здесь: https://stackoverflow.com/questions/651 ... le-threads
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»