代码之家  ›  专栏  ›  技术社区  ›  finnw

在单独的线程中安全地更新BufferedImage的单独区域?

  •  5
  • finnw  · 技术社区  · 14 年前

    我收集了 BufferedImage 通过调用创建的实例、一个主映像和一些子映像 getSubImage 在主图像上。子图像不重叠。我也在修改子映像,我想把它分成多个线程,每个子映像一个。

    从我对如何 缓冲图像 , Raster DataBuffer 工作,这应该是安全的,因为:

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

    但是,我在文档中找不到任何说明这样做绝对安全的内容。我能假设它是安全的吗?我知道这孩子的复制品是可能的 光栅 但是由于内存限制,我更愿意避免这种情况。

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

    4 回复  |  直到 14 年前
        1
  •  4
  •   Jeff    14 年前

    你有没有研究过用jai把你的“子图像”作为块来管理?如果您不必挂起原始图像BufferedImage实例及其所有子图像BufferedImage实例,那么似乎可以更好地使用资源。有关JAI的信息可在此处找到: JAI README

    有一个类,tiledimage,它实现了renderedimage接口(给它一个与bufferedimage相同的祖先)。根据JAI文件:

    瓷砖的使用也有助于 多线程用于 计算。以前分配的 瓷砖也可以重新用于保存 记忆。

    使用renderedImage的其中一个实现通常比bufferedImage更受欢迎,因为bufferedImage在内存中为整个图像维护一个图像快照。JAI使用一个渲染链,可以根据需要回收瓷砖以适应内存限制。

        2
  •  2
  •   mdma    14 年前

    这是一个很好的分析,对我来说是正确的。没有共享数据,所以并发访问应该可以。然而,你需要某种保证来确定,而不仅仅是一个有教育意义的猜测,它应该起作用。即使您发现一条语句说“bufferedimage设计为并发使用”——也不能保证这是实际情况。

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

        3
  •  1
  •   leopoldkot    14 年前

    我没有发现任何明显的证据表明 BufferedImage 但是你可能可以用下一种方法来解决你的问题:

    不要让不同的工作人员同时处理子图像,而是尝试以每个工作人员使用同一图像的不同子图像的方式处理多个图像。同一个工人将处理同一图像的子图像,但顺序相同。

    你的工人会很忙,直到没有比工人们留下的更少的图像。

    还原此问题:

            W1       W2      W3
    Img1 |-------|-------|-------|
            W1       W2      W3
    Img2 |-------|-------|-------|
    
    到:
            W1       W1      W1
    Img1 |-------|-------|-------|
            W2       W2      W2
    Img2 |-------|-------|-------|
        
        4
  •  0
  •   Allen    14 年前

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

    Examine the source for BufferedImage, DataBuffer, Raster, etc. 这是唯一的办法。