1

I have a question about the method write of the ImageIO class from the package javax.imageio
Can i call the method
ImageIO.write(bufferedImage, 'jpg', new File(...))
with bufferedImage different instances for each threads
So I want to know if it's thread safe or not in my case. And why this method could be thread safe. Thanks in advance!

Edit: @yshavit, yes it's in order to write in different files
For the other thread I read it, but I didn't quite well understand why it could be for sure thread safe as haraldK says.

DevAy.T
  • 19
  • 3
  • I doubt it is, but I'm not sure. A common technique is to write to a tmp location, and then move it to where you want it to go -- which is often atomic, or as atomic as you're going to get on a given file system. – yshavit May 22 '17 at 18:23
  • Provided you are not attempting to write to the same file - I do not see why this would not be thread safe. – Matt Clark May 22 '17 at 18:23
  • Ah, yes. I was assuming writing to the same file. OP, can you clarify? – yshavit May 22 '17 at 18:24
  • If each call uses a different BufferedImage and a different file path, it’s completely thread safe. However, writing to multiple files simultaneously on the same storage device is unlikely to bring a significant performance benefit. – VGR May 22 '17 at 18:51
  • The performance benefit in my application it's to get a region of an original image by thread and save those cropped images with imageIO.write in order to process them by ffmpeg to make a video clip from it – DevAy.T May 22 '17 at 19:03
  • 1
    The fact that it's static implies that it would be thread safe: it would be a very poor API design if there was no way to call it from multiple threads *and* not document the method as being thread unsafe. (Of course, the Java API has no examples of poor API design...) – Andy Turner May 22 '17 at 19:09
  • Yes it's thread safe. Should you find any evidence on the contrary, it is a bug, and you should report it. PS: I updated my answer that @Sam referred to. – Harald K May 23 '17 at 08:02
  • Thank you all for your answers. – DevAy.T May 23 '17 at 08:26
  • @DevAy.T I'm not completely happy about SO allowing me alone to close this as a duplicate, so if you are still unsure, feel free to edit your question and I'll consider re-opening it. But as it is, I'm confident that this is a duplicate. – Harald K May 23 '17 at 08:29
  • No it's ok, you can close it. Thank you all for your answers and clarification. – DevAy.T May 23 '17 at 09:03

1 Answers1

1

Can i call the method ImageIO.write(bufferedImage, 'jpg', new File(...))... I want to know if it's thread safe...

Sounds like you are trying to call ImageIO.write(...) in multiple threads with different bufferedImage all writing to the same File. This is not going to be a problem in terms of the code being "thread safe". By calling from different threads using different bufferedImage, there isn't going to be memory overwrite issues or other problems that we typically worry about with threads.

However, there are race conditions that might generate an invalid image file. In looking at the FileImageOutputStream, if 2 threads are writing into the same RandomAccessFile at the same time, you certainly could get sections of the file written by one thread with other sections written by the other thread resulting in a broken image.

I would recommend that each thread writes into their own temporary file and then rename the file into place:

// write to temporary file with thread-id suffix
File tempFile =
     new File(destinationDirectory + fileName + Thread.currentThread().getId() + ".t");
ImageIO.write(bufferedImage, 'jpg', tempFile);
// rename into place
tempFile.rename(new File(fileName));

The File.rename(...) method is an atomic operation. It's doesn't save you from the fact that the 2nd thread that calls rename will delete the 1st thread's output but it will save you from a corrupted image.

Gray
  • 115,027
  • 24
  • 293
  • 354
  • Thank you for your answer. In my case I don't have race conditions problem because I save each bufferedImage in different files. My question was about the scenario of 2 threads (or more) executing at the very same time the `ImageIO.write(..., ..., ...)`   method – DevAy.T May 23 '17 at 07:58