IOUtils.toByteArray (входной поток) потокобезопасен?

#java #multithreading #concurrency #ioutils

#java #многопоточность #параллелизм #ioutils

Вопрос:

Может ли использование IOUtils.ToByteArray привести к проблемам параллелизма?

 private byte[] saveLetterContent(InputStream input) {
  ...

  byte[] letterContent = IOUtils.toByteArray(input);

  ...
}
 

Я имею в виду, возможно ли, что letterContent в этом методе неправильное изменение из-за параллелизма?

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

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

2. Вы пытаетесь вызвать saveLetterContent для одного и того же экземпляра в InputStream более чем в одном потоке? Я действительно сомневаюсь :)… Но если да, то чего именно вы пытаетесь достичь?

Ответ №1:

Я имею в виду, возможно ли, что letterContent в этом методе изменяется неправильно из-за параллелизма?

Безусловно, вызов toByteArray(InputStream) без защиты введенного InputStream может привести к неопределенному поведению. Это также легко продемонстрировать.

 final String value = "hello! ciao!";
final byte[] valueBytes = value.getBytes(StandardCharsets.UTF_8);
System.out.println(valueBytes.length);

final ByteArrayInputStream is = new ByteArrayInputStream(valueBytes);

new Thread(() -> {
   try {
      is.read(new byte[10]);
   } catch (final IOException e) {
      //
   }
}).start();

// Thread.sleep(50)

final byte[] bytes = IOUtils.toByteArray(is);
System.out.println(bytes.length);
 

В приведенном выше примере вы наверняка заметите, что второй System.out будет печатать меньшую длину байтов, чем первый. Вы даже можете поиграть Thread.sleep и посмотреть, что произойдет.

введите описание изображения здесь

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

1. какая лучшая альтернатива для toByteArray в многопоточном приложении?

2. @elahe нет, вы должны синхронизировать использование входного потока самостоятельно.

3. Я думаю, что в вашем коде порядок потоков не гарантирует порядок вывода

4. @elahe мой код не синхронизируется специально

5. @elahe вам нужно обернуть обычаи блокировками или синхронизированными блоками