CharsetDecoder иногда выдает исключение IllegalStateException при вызове с использованием .stream().collect(Коллекторы.toMap(…))

#java #parallel-processing #character-encoding #hashmap #illegalstateexception

#java #параллельная обработка #кодировка символов #hashmap #исключение illegalstateexception

Вопрос:

Иногда я получаю IllegalStateException при вызове CharsetDecoder.decode(ByteBuffer in) . Я вызываю это из (того, что, я думаю, должно быть) последовательной toMap операции.

Исключение описывает состояние декодера как Current state = CODING_END, new state = FLUSHED .

CharsetDecoder Инициализируется с помощью java.nio.charset.Charset.forName("UTF-8").newDecoder() . Операция декодирования окружена блоком try / catch. Я попытался явно добавить finally блок, в котором я сбрасываю декодер, хотя в документации указано, что это должно быть сделано в начале операции декодирования. С этим изменением я по-прежнему получаю то же исключение, но состояние описывается как Current state = RESET, new state = FLUSHED .

Я использую декодер в фрагменте кода, подобном этому:

 return someMap.entrySet().stream().collect(Collectors.toMap(
    Map.Entry::getKey,
    entry -> methodThatDecodes(entry.getValue())
));
  

где methodThatDecodes что-то вроде:

 String methodThatDecodes(Future<ByteBuffer> futureIn) {
    ByteBuffer in = futureIn.get(10, TimeUnits.SECONDS);
    return decoder.decode(in).toString();
}
  

Иногда это выдает сообщение, IllegalStateException для CharsetDecoder которого в документации указано, что это означает, что декодер все еще используется. Поскольку я не использую parallelStream() , я не уверен, почему это происходит. В документации указано, что decode(ByteBuffer in) это удобный метод, который выполняет сброс и промывку для декодера, и поскольку он вызывается последовательно, декодер никогда не должен использоваться при вызове этого метода.

Комментарии:

1. Не могли бы вы опубликовать трассировку стека? Кажется странной проблемой.

2. @LppEdd Вызвано: java.lang. Исключение IllegalStateException: текущее состояние = СБРОС, новое состояние = СБРОС в java.nio.charset. CharsetDecoder.throwIllegalStateException(CharsetDecoder.java:992) в java.nio.charset. CharsetDecoder. сброс(CharsetDecoder.java:675) в java.nio.charset. CharsetDecoder.decode(CharsetDecoder.java:804) в <моем методе>

3. Декодер является полем класса или локальной переменной?

4. поле класса @LppEdd, введенное guice.

5. Это содержащий экземпляр класса, используемый несколькими потоками? Вы пробовали применить к нему синхронизацию?