2014-02-21 103 views
0

我有一個使用JCGM API讀取圖像的靜態方法。這段代碼不是線程安全的嗎?

public static BufferedImage readBlackAndWhite(final ImageInputStream pIntputstream, 
    Dimension pDim) throws IOException { 
    ImageReaderSpi lCgmImageReaderSpi = new CGMImageReaderSpi(); 
    CGMImageReader lReader = new CGMImageReader(lCgmImageReaderSpi); 
    lReader.setBlackAndWhite(true); 
    lReader.setInput(pIntputstream); 
    return lReader.read(0, pDim.width, pDim.height); 
} 

我認爲這是不是線程安全的。因爲這種方法是靜態的,pIntputstreampDim會導致多線程環境中的問題。

將同步添加到方法定義將使其線程安全。 但降低性能

我想知道什麼是使這個方法線程安全的其他最好的方法。記住性能?

+0

爲了更安全的一面,您還可以使用runnable接口。 –

+0

這個問題現在非常普遍,這是一個非常廣泛的話題。沒有最好的方式去關於線程安全。 – Radiodef

+0

像@radiodef說的那樣,這是一個普遍的問題。考慮到「Dimension」是可變的,該方法本身不是線程安全的。 – hofmeister

回答

0

如果超過1個線程調用readBlackAndWhitepIntputstream相同,那麼它可能是不安全的。 InputStreams通常通過對其read方法的多次調用以塊來讀取。想象許多線程在相同的輸入流中互換地調用read,聽起來很糟糕,不是嗎?

使其同步應該是安全的,因爲在任何給定的實例中只有一個線程可以位於readBlackAndWhite之內,但正如您所提到的那樣,它會降低吞吐量。

如果你不想讓它同步,我能想到的其他方法是爲每個線程提供它自己的InputStream副本以供讀取,因此它與其他線程完全隔離。

2

你的代碼是線程安全的,如果你能保證以下幾點:

1)您的流不與其他線程(數據流很少是線程安全的共享 - 他們希望通過一個單獨的線程來處理)

2)你的Dimension對象是:a)不可變b)不與其他任何線程共享c)線程安全d)有效的不可變 - 意味着其他線程可能操作它,但隨後以安全的方式發佈給其他線程使用自那時以來沒有發生任何狀態修改。

3)CGMImageReaderSpi和CGMImageReader的構造函數以及ImageInputStream的讀取方法不會與一些與其他線程共享的狀態變量混淆。

或者,如果上述一項或多項不成立,則代碼仍然可以是線程安全的,如果它總是以互斥的方式使用某種鎖定(例如同步塊)執行。