Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ImageIO thread-safety

I see in the javax.imageio spec that thread-safety is not a goal, despite I've seen several examples using ImageIO.read() and ImageIO.write() for uploading/sanitizing images in a web environment.

So, my question is, despite what the spec says, is ImageIO thread-safe?

like image 996
Alex Avatar asked Oct 10 '14 10:10

Alex


2 Answers

ImageIO is not thread safe (or at least one of it's plugins is not), in at least one of my environments. I am in the process of debugging an issue where png and jpg files don't get loaded correctly (sometimes solid gray, sometimes inverted colors, sometimes random colors, etc) when ImageIO.read() is invoked from multiple threads. I also occasionally get ConcurrentModificationExceptions like:

java.util.ConcurrentModificationException
at java.util.Vector$Itr.checkForComodification(Vector.java:1184)
at java.util.Vector$Itr.next(Vector.java:1137)
at sun.java2d.cmm.ProfileDeferralMgr.activateProfiles(ProfileDeferralMgr.java:93)
at java.awt.color.ICC_Profile.getInstance(ICC_Profile.java:777)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.setImageData(JPEGImageReader.java:657)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readImageHeader(Native Method)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readNativeHeader(JPEGImageReader.java:609)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.checkTablesOnly(JPEGImageReader.java:347)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.gotoImage(JPEGImageReader.java:481)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readHeader(JPEGImageReader.java:602)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(JPEGImageReader.java:1059)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:1039)
at javax.imageio.ImageIO.read(ImageIO.java:1448)
at javax.imageio.ImageIO.read(ImageIO.java:1308)
at com.foo.bar.MyTestLoadThread.loadImage(MyTestLoadThread.java:241)
...
at java.lang.Thread.run(Thread.java:745)

I am not able to replicate this behavior in all environments so it may be JVM specific. But here are the details of the env. where I see it fail:

  • OS : Ubuntu 14.04
  • java -version :
    java version "1.8.0_33"
    Java(TM) SE Runtime Environment (build 1.8.0_33-b05)
    Java HotSpot(TM) Client VM (build 25.33-b05, mixed mode)
like image 170
preston.m.price Avatar answered Sep 22 '22 20:09

preston.m.price


TLDR; Yes, the static methods ImageIO.read(...) and write(...) are thread safe.


The part of the specification that says "thread safety is not a goal" needs to be read in context. What the spec actually says, is that individual ImageReader, ImageWriter or ImageInputStream/ImageOutputStream implementations do not need to be concerned with thread safety (and as a result, client code should never assume they are thread safe). As long as you live by this rule, you are safe. Note however, that the same part of the spec also states that:

[...] it must be possible for multiple instances of the same plug-in class to operate simultaneously.

This part of the specification does not discuss the static methods of ImageIO especially, but the above quote implies that tese methods are thread safe, as ImageIO.read(...) and write(...) creates new instances of ImageInputStream/ImageOutputStream and ImageReader/ImageWriter for each invocation. So, it's not really "despite what the spec says".

The ImageIO class consists of several other static methods that are safe to use, and the class itself is (mostly*) stateless. If it didn't work this way, it wouldn't really be of much use...

*) The IIORegistry instance of ImageIO is populated at class creation time, and re-initialized whenever the scanForPlugins() method is invoked. You might run into problems (i.e. plugins might not be correctly registered) if two threads invoke it the same time, but as client code control where/when it happens, you can easily avoid that. There's also the per thread group CacheInfo, but its usage seems to be properly synchronized.


Disclaimer, I didn't write the spec, but this is my interpretation (and I have used ImageIO in countless, multithreaded applications, as well as written a dozen or so ImageReader and ImageWriter plugins myself).

like image 45
Harald K Avatar answered Sep 20 '22 20:09

Harald K