6

我有一组BufferedImage实例,一个主图像和一些通过调用getSubImage主图像创建的子图像。子图像不重叠。我也在对子图像进行修改,我想将其拆分为多个线程,每个子图像一个。

根据我对如何和工作的理解BufferedImage,这应该是安全的,因为:RasterDataBuffer

  • BufferedImage(及其各自的WritableRasterand )的每个实例SampleModel只能从一个线程访问。
  • 共享ColorModel是不可变的
  • 没有可以修改的DataBuffer字段(唯一可以更改的是支持数组的元素。)
  • 在单独的线程中修改数组的不相交段是安全的。

但是,我在文档中找不到任何说明这样做绝对安全的内容。我可以假设它是安全的吗?我知道可以处理 childRaster的副本,但由于内存限制,我更愿意避免这种情况。

否则,是否可以在不复制父图像区域的情况下使操作线程安全?

4

4 回答 4

4

您是否考虑过使用 JAI 将您的“子图像”作为图块进行管理?如果您不必挂在原始图像 BufferedImage 实例及其所有 subImage BufferedImage 实例上,这似乎是对资源的更好利用。关于 JAI 的信息可以在这里找到: JAI README

有一个类 TiledImage,它实现了 RenderedImage 接口(给它一个与 BufferedImage 共同的祖先)。根据 JAI 文档:

平铺的使用还有助于使用多个线程进行计算。先前分配的图块也可以重新使用以节省内存。

无论如何,使用 RenderedImage 的这些实现之一通常比使用 BufferedImage 更可取,因为 BufferedImage 在内存中维护整个图像的图像快照。JAI 使用渲染链,可以根据需要回收切片以适应内存限制。

于 2010-05-21T17:58:57.153 回答
2

这是一个很好的分析,对我来说听起来是正确的。没有共享数据,所以并发访问应该没问题。但是,您需要某种保证来确定,而不是有根据地猜测它应该有效。即使您发现“BufferedImage 旨在同时使用”的声明 - 也不能保证在实践中就是这种情况。

为了尽可能确定,您可以使用ConTest编写并发单元测试。并发测试工具检测您的代码并注入人为诱导的上下文切换以暴露并发错误。这将测试 BufferedImage 代码和您自己的代码,因此您可以高度确信它是线程安全的。

于 2010-05-23T20:11:39.010 回答
1

我还没有找到任何明确的线程安全证据BufferedImage,但您可能可以通过以下方式解决您的问题:

与其同时处理不同工作人员的子图像,不如尝试以每个工作人员消耗同一图像的不同子图像的方式处理许多图像。同一个工作人员将按顺序处理同一图像的子图像。

您的工作人员会很忙,直到图像数量少于剩余的工作人员。

恢复这个问题:

        W1 W2 W3
Img1 |-------|-------|--------|
        W1 W2 W3
Img2 |-------|--------|--------|
到:

        W1 W1 W1
Img1 |-------|-------|--------|
        W2 W2 W2
Img2 |-------|--------|--------|
    
于 2010-05-21T11:14:53.863 回答
0

如果这些答案都不能满足(足够)你可以做一些事情,最终以沉重的(?)价格解决问题。

检查 BufferedImage、DataBuffer、Raster 等的来源。这是唯一的方法。

于 2010-05-23T22:50:56.627 回答