Safe to update separate regions of a BufferedImage in separate threads?

蹲街弑〆低调 提交于 2019-12-05 10:55:55

Have you looked into using JAI to manage your 'subimages' as tiles? It seems like a better use of resources if you don't have to hang onto the original image BufferedImage instance as well as all its subImage BufferedImage instance. Information about JAI can be found here: JAI README

There is a class, TiledImage, which implements the RenderedImage interface (giving it a common ancestor with BufferedImage). According to the JAI documentation:

The use of tiling also facilitates the use of multiple threads for computation. Previously allocated tiles may also be re-used to save memory.

Using one of these implementations of RenderedImage is often preferrable to a BufferedImage anyway, since the BufferedImage maintains an image snapshot in memory for the entire image. JAI uses a rendering chain and can recycle tiles as needed to fit memory constraints.

That's a good analysis, and it sounds correct to me. There is no shared data, so concurrent access should be fine. However, you need some kind of guarantee to be sure, more than a educated guess that it should work. Even if you find a statement saying "BufferedImage is designed to be used concurrently" - there is no guarantee that this is the case in practice.

To be as sure as you can be, you can write a concurrent unit test using ConTest. The concurrent test harness instruments your code and injects artificially induced context switches to expose concurrency bugs. This will test the BufferedImage code and your own code, so you can have a high degree of confidence that it is thread safe.

I haven't found any clear evidence of thread safety of BufferedImage, but you probably can solve your problem the next way:

Instead of simultaneous processing of subimages by different workers, try to process many images in the way that every worker consumes different subimages of the same image. The same worker will be processing subimages of the same image, but sequentially.

Your workers would be busy until there are less images than workers remained.

Revert this problem:

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

If none of these answers satisfy (enough) you could do something that will conclusively settle the question at a heavy(?) price.

Examine the source for BufferedImage, DataBuffer, Raster, etc. It's the only way.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!