我在使用多线程环境中的
Image IO帮助读取
Java图像时遇到问题.只有多个线程尝试读取图像时才会出现问题.
症状从错误的配置文件加载到异常有所不同:
java.awt.color.CMMException: LCMS error 13: Couldn't link the profiles
无论我如何阅读图像,通过ImageIO.read或使用ImageReader.
源数据(图像)完全隔离且不可变.
这个问题可能与:
https://bugs.openjdk.java.net/browse/JDK-8041429和
https://bugs.openjdk.java.net/browse/JDK-8032243
问题是有没有其他方法可以使用具有多个线程的ImageIO读取JPEG文件.看起来ImageIO中存在问题,共享我无法控制的图像颜色配置文件的可变状态.我看到的唯一解决方案是在JVM级别完全隔离它,这听起来不错.
我使用的是Oracle JDK 8u25.更改JDK更新版本对问题没有影响(不是主要版本),我不能在不重写大块代码的情况下使用JDK 7.
代码供参考.
ImageInputStream input = new MemoryCacheImageInputStream(inputStream); Iterator<ImageReader> readers = ImageIO.getImageReaders(input); if (!readers.hasNext()) { throw new IllegalArgumentException("No reader for: " + dataUuid.toString()); } ImageReader reader = readers.next(); try { reader.setInput(input); BufferedImage image = reader.read(0,reader.getDefaultReadParam());
解决方法
在JVM start上添加一个钩子.在钩子中,只需:
Class.forName("javax.imageio.ImageIO");
这将强制类加载器加载类并执行它需要的任何静态初始化.我认为你的问题是在线程上加载了类,而第二个线程正在尝试使用ImageIO,这会导致在颜色配置文件上获得锁定(或缺少锁定)的冲突.
编辑:您也可以将此行添加到您的主页.确保它是您拨打的第一行.
ImageIO不是负责ColorSpace初始化的类.
Class.forName("java.awt.color.ICC_ColorSpace"); Class.forName("sun.java2d.cmm.lcms.LCMS");
诀窍很难.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。