在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");
}
为什么这两种方法同步而其他方法都不同步?
答案 0 :(得分:6)
有一些矛盾的事实表明synchronized关键字在这里只是一个错误:
当然,这只是开发人员的一个提示。方法为空,并且子类中不继承synchronized
关键字。
另一方面,其他方法不同步,甚至是抽象和空方法。这意味着我们被警告不要忘记标记/重置上的同步,但我们没有收到关于并发read()
调用的警告。这没有意义,因为没有同步,并发读取将无法工作。
许多JDK流实现对同步关键字的使用不一致。
java.io.InputStream
与java.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类可以处理多线程,并且还应该实现类。