2014-02-21 77 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的读取方法不会与一些与其他线程共享的状态变量混淆。

或者,如果上述一项或多项不成立,则代码仍然可以是线程安全的,如果它总是以互斥的方式使用某种锁定(例如同步块)执行。