2010-05-18 123 views
5

我有一個BufferedImage實例的集合,一個主圖像和通過在主圖像上調用getSubImage創建的一些子圖像。子圖像不重疊。我也在修改子圖像,我想把它分成多個線程,每個子圖像一個。安全地更新單獨線程中BufferedImage的單獨區域?

從我如何BufferedImageRasterDataBuffer的工作,這應該是安全的理解,因爲:

  • BufferedImage每個實例(及其各自WritableRasterSampleModel)從只有一個線程訪問。
  • 共享ColorModel是不可改變
  • DataBuffer沒有字段可被修改(即可以改變的唯一事情是在背襯數組的元素。)
  • 修改陣列的不相交的段中獨立的線程是安全的。

但是我找不到任何文件說明這樣做絕對安全。我可以認爲它是安全的嗎?我知道可以在兒童Raster的副本上工作,但由於內存限制,我寧願避免這種情況。

否則,是否可以使操作線程安全,而無需複製父圖像的區域?

回答

4

你有看着使用JAI來管理你的 '子圖' 瓷磚?如果您不必掛在原始圖像BufferedImage實例以及其所有的SubImage BufferedImage實例上,它似乎可以更好地使用資源。關於JAI的信息可以在這裏找到: JAI README

有一個類,TiledImage,實現RenderedImage接口(給它與BufferedImage共同的祖先)。按照JAI文檔:

使用平鋪也有利於爲 計算的 使用多個線程。先前分配的 瓷磚也可能被重新用於保存 內存。

無論如何,使用RenderedImage的這些實現之一通常更適合BufferedImage,因爲BufferedImage在整個圖像的內存中維護一個圖像快照。JAI使用渲染鏈並根據需要回收瓦片以適應內存限制。

1

我還沒有發現的BufferedImage線程安全的任何明確的證據,但你可能可以解決你的問題,接下來的路:

而是由不同的工人子圖像的同時處理,儘量處理在許多圖像每個工作人員消費同一圖像的不同子圖像的方式。同一個工作人員將會處理同一圖像的子圖像,但是會依次處理。

你的工作人員會很忙,直到圖像少於工作人員。

還原這個問題:

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

 
     W1  W1  W1 
Img1 |-------|-------|-------| 
     W2  W2  W2 
Img2 |-------|-------|-------| 
+0

然後分割圖像沒有優勢。 – finnw 2010-05-21 12:51:43

+0

我寧願繼續處理多個線程中的單個圖像的子圖像,以保持延遲。即使事實證明它需要複製子圖像。 – finnw 2010-05-21 12:52:57

2

這是一個很好的分析,對我來說這聽起來是正確的。沒有共享數據,所以併發訪問應該沒問題。但是,您需要確保某種保證,而不是一個有教育的猜測,它應該有效。即使您發現一條聲明「BufferedImage旨在同時使用」 - 不能保證在實踐中會出現這種情況。

爲了儘可能確保您可以使用ConTest編寫併發單元測試。併發測試工具用於測試您的代碼並注入人工引發的上下文切換以顯示併發錯誤。這將測試BufferedImage代碼和您自己的代碼,因此您可以高度確信它是線程安全的。