簡體   English   中英

ImageIO線程安全

[英]ImageIO thread-safety

我在javax.imageio規范中看到線程安全不是目標,盡管我已經看到了幾個使用ImageIO.read()ImageIO.write()在Web環境中上傳/清理圖像的示例。

所以,我的問題是,盡管規范說的是, ImageIO線程安全嗎?

至少在我的一個環境中,ImageIO不是線程安全的(或至少其中一個插件不是)。 我正在調試一個問題,當從多個線程調用ImageIO.read()時,png和jpg文件無法正確加載(有時是純灰色,有時是反色,有時是隨機顏色等)。 我偶爾也會得到ConcurrentModificationExceptions,例如:

java.util.ConcurrentModificationException
at java.util.Vector$Itr.checkForComodification(Vector.java:1184)
at java.util.Vector$Itr.next(Vector.java:1137)
at sun.java2d.cmm.ProfileDeferralMgr.activateProfiles(ProfileDeferralMgr.java:93)
at java.awt.color.ICC_Profile.getInstance(ICC_Profile.java:777)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.setImageData(JPEGImageReader.java:657)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readImageHeader(Native Method)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readNativeHeader(JPEGImageReader.java:609)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.checkTablesOnly(JPEGImageReader.java:347)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.gotoImage(JPEGImageReader.java:481)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readHeader(JPEGImageReader.java:602)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(JPEGImageReader.java:1059)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:1039)
at javax.imageio.ImageIO.read(ImageIO.java:1448)
at javax.imageio.ImageIO.read(ImageIO.java:1308)
at com.foo.bar.MyTestLoadThread.loadImage(MyTestLoadThread.java:241)
...
at java.lang.Thread.run(Thread.java:745)

我無法在所有環境中復制此行為,因此它可能是特定於JVM的。 但這里是環境的細節。 在哪里我看到它失敗了:

  • 操作系統:Ubuntu 14.04
  • java -version:
    java版“1.8.0_33”
    Java(TM)SE運行時環境(版本1.8.0_33-b05)
    Java HotSpot(TM)客戶端VM(版本25.33-b05,混合模式)

TLDR; 是的,靜態方法ImageIO.read(...)write(...)是線程安全的。


規范中稱“線程安全不是目標”的部分需要在上下文中閱讀。 實際上說的是,單獨的ImageReaderImageWriterImageInputStream/ImageOutputStream實現不需要關心線程安全性(因此,客戶端代碼永遠不應該假設它們是線程安全的)。 只要你遵守這條規則,你就是安全的。 但請注意,規范的相同部分還指出:

[...]同一個插件類的多個實例必須同時運行。

規范的這一部分並沒有特別討論ImageIO的靜態方法,但上面的引用暗示tese方法是線程安全的,因為ImageIO.read(...)write(...)創建了ImageInputStream / ImageOutputStream新實例和每個調用的ImageReader / ImageWriter 所以,它並不是“盡管規范說的”

ImageIO類由幾個可以安全使用的靜態方法組成,類本身(大多數是*)是無狀態的。 如果它不能以這種方式工作,它就沒有多大用處......

*) ImageIOIIORegistry實例在類創建時填充,並在調用scanForPlugins()方法時重新初始化。 如果兩個線程同時調用它,您可能會遇到問題(即插件可能沒有正確注冊),但是當客戶端代碼控制它發生的地方/時間時,您可以輕松避免這種情況。 還有每個線程組CacheInfo ,但它的用法似乎正確同步。


免責聲明,我沒有編寫規范,但這是我的解釋(我在無數的多線程應用程序中使用過ImageIO ,並且自己編寫了十幾個ImageReaderImageWriter插件)。

我檢查了班級,沒有州和幾乎所有無國籍的班級。 (我沒有檢查所有功能。最好在使用前檢查功能)

最有可能是線程安全。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM