首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ImageIO线程安全

ImageIO线程安全
EN

Stack Overflow用户
提问于 2014-10-10 10:38:53
回答 2查看 3.1K关注 0票数 7

我在javax.imageio规范中看到,线程安全并不是一个目标,尽管我已经看到了几个在web环境中使用ImageIO.read()ImageIO.write()上传/消毒图像的例子。

所以,我的问题是,不管规范怎么说,ImageIO线程安全吗?

EN

回答 2

Stack Overflow用户

发布于 2015-08-26 20:20:56

至少在我的一个环境中,ImageIO并不是线程安全的(或者至少有一个插件不是)。我正在调试一个问题,当从多个线程调用ImageIO.read()时,png和jpg文件无法正确加载(有时是纯色的灰色,有时是倒置的颜色,有时是随机的颜色等等)。我偶尔也会得到ConcurrentModificationExceptions,比如:

代码语言:javascript
复制
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)

我不能在所有的环境中复制这种行为,所以它可能是JVM特定的。但以下是环境保护局的细节。在我看来失败的地方:

  • 操作系统: Ubuntu 14.04
  • java -version: java版本"1.8.0_33“ Java(TM) SE运行时环境(build 1.8.0_33.B05) Java HotSpot(TM)客户端VM (build 25.33-b05,混合模式)
票数 8
EN

Stack Overflow用户

发布于 2014-10-10 13:16:04

是的,静态方法ImageIO.read(...)write(...)是线程安全的。

规范中说明https://docs.oracle.com/javase/8/docs/technotes/guides/imageio/spec/goals.fm2.html的部分需要在上下文中阅读。规范实际上说的是,单独的ImageReaderImageWriterImageInputStream/ImageOutputStream实现不需要关注线程安全(因此,客户端代码永远不应该假定它们是线程安全的)。只要你遵守这条规则,你就安全了。但是,请注意,规范的同一部分还指出:

..。同一插件类的多个实例必须能够同时操作。

规范的这一部分没有特别讨论ImageIO的静态方法,但是上面的引用意味着tese方法是线程安全的,因为ImageIO.read(...)write(...)为每次调用创建了新的ImageInputStream/ImageOutputStreamImageReader/ImageWriter实例。所以,这并不是真正的“不管规范怎么说”。

ImageIO类由其他几个安全使用的静态方法组成,类本身(大部分是*)是无状态的。如果不是这样的话,那就没什么用了.

*)在类创建时填充ImageIOImageIO实例,并在调用scanForPlugins()方法时重新初始化。如果两个线程同时调用插件,您可能会遇到问题(即插件可能无法正确注册),但作为客户端代码控制,可以很容易地避免这种情况发生。还有每个线程组CacheInfo,但是它的使用似乎是正确同步的。

免责声明,我没有编写规范,但这是我的解释(我在无数多线程应用程序中使用了ImageIO,并自己编写了十几个ImageReaderImageWriter插件)。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26297491

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档