加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

Java中的多线程JPEG图像处理

发布时间:2020-12-14 23:59:01 所属栏目:Java 来源:网络整理
导读:我在使用多线程环境中的 Image IO帮助读取 Java图像时遇到问题.只有多个线程尝试读取图像时才会出现问题. 症状从错误的配置文件加载到异常有所不同: java.awt.color.CMMException: LCMS error 13: Couldn't link the profiles 无论我如何阅读图像,通过Image
我在使用多线程环境中的 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");

诀窍很难.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读