Java IO Streams中的同步方法

时间:2015-11-04 15:39:45

标签: java multithreading concurrency synchronization

在Java中,自类java.io.InputStream中的Java 1.0以来就有方法

public synchronized void mark(int readlimit) {}

public synchronized void reset() throws IOException {
    throw new IOException("mark/reset not supported");
}

为什么这两种方法同步而其他方法都不同步?

3 个答案:

答案 0 :(得分:6)

有一些矛盾的事实表明synchronized关键字在这里只是一个错误:

  1. 当然,这只是开发人员的一个提示。方法为空,并且子类中不继承synchronized关键字。

  2. 另一方面,其他方法不同步,甚至是抽象和空方法。这意味着我们被警告不要忘记标记/重置上的同步,但我们没有收到关于并发read()调用的警告。这没有意义,因为没有同步,并发读取将无法工作。

  3. 许多JDK流实现对同步关键字的使用不一致。

  4. java.io.InputStreamjava.nio.Buffer相反,几乎没有任何有用的基本方法实现,但却成了一个类。因此,它试图在这个“骨架提供”和宣布一般方法合同之间取得平衡。

答案 1 :(得分:0)

这是因为你可以在文档中看到mark()和reset()一起工作。

  

public void mark(int readlimit):   标记此输入流中的当前位置。随后对reset方法的调用会在最后标记的位置重新定位此流   位置,以便后续读取重新读取相同的字节。

如果您有多个共享相同InputStream的线程,如果这两种方法不能同步,则可能会导致问题。

更新评论

java.io.InputStream是一个抽象类,所以我认为synchronized对于继承InputStream作为提示的类更多。如果mark()返回true,则仅使用方法reset()markSupported()。在课程java.io.InputStream#markSupported()中返回false。

/**
 * Tests if this input stream supports the <code>mark</code> and
 * <code>reset</code> methods. Whether or not <code>mark</code> and
 * <code>reset</code> are supported is an invariant property of a
 * particular input stream instance. The <code>markSupported</code> method
 * of <code>InputStream</code> returns <code>false</code>.
 *
 * @return  <code>true</code> if this stream instance supports the mark
 *          and reset methods; <code>false</code> otherwise.
 * @see     java.io.InputStream#mark(int)
 * @see     java.io.InputStream#reset()
 */
public boolean markSupported() {
    return false;
}

答案 2 :(得分:-1)

由于mark()和reset()方法内部没有代码,因此单词&#34; synchronized&#34;只是一个提醒&#34;在它们覆盖它们时实现应该锁定或在这些方法中的类。这是为了防止多线程用例的竞争条件。

现在,其他InputStream方法没有被标记为&#34; synchronized&#34;因为这些方法永远不会抛出IndexOutOfBoundsException,BufferOverflowException等。 (除非传入错误的缓冲区大小)。当没有更多字节要读取而不是抛出异常时,这些方法总是返回-1。所以他们不需要同步。

您会注意到read()是抽象的。并且实现类确实指定&#34; synchronized&#34;当他们实施这种方法时。

换句话说,抽象的InputStream类可以处理多线程,并且还应该实现类。