这段代码不是线程安全的吗?

时间:2014-02-21 06:10:32

标签: java multithreading

我有一个使用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将导致多线程环境中出现问题。

将synchronized同步添加到方法定义将使其线程安全。 但降低性能

我想知道使这个方法线程安全的另一种最佳方法是什么。记住表现?

2 个答案:

答案 0 :(得分:2)

如果您保证以下内容,您的代码是线程安全的:

1)您的流不与其他线程共享(Streams很少是线程安全的 - 它们希望由单个线程处理)

2)您的Dimension对象是:a)不可变b)不与任何其他线程共享c)线程安全d)有效不可变 - 意味着其他线程可能操纵它,但随后以安全的方式为其他线程发布使用,此后没有任何州修改。

3)CGMImageReaderSpi和CGMImageReader的构造函数,以及ImageInputStream的read方法都没有弄乱一些与其他线程共享的状态变量。

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

答案 1 :(得分:0)

如果有多个线程使用相同的readBlackAndWhite调用pIntputstream,那么它可能不安全。 InputStream通常是通过多次调用其read方法读取的。想象一下,许多线程在相同的输入流上互换地调用read,听起来不好不是吗?

使它同步应该使它安全,因为在任何给定的实例中只有一个线程可以在readBlackAndWhite内,但正如你所提到的那样会降低吞吐量。

如果你不想让它同步,我能想到的其他方法是用每个线程提供自己的InputStream副本进行读取,因此它与其他线程完全隔离。