这一篇的内容本来可以和上一篇写在一起,感觉特别重要,因此单独拿出来了 1 关于通道(Socket)读/写线程安全下面是ReadableByteChannel和WriteByteChannel接口的说明:
下面是两个接口的read和write方法的说明 Suppose that a byte sequence of length n is written, where 0 <= n <= r. This byte sequence will be transferred from the buffer starting at index p, where p is the buffer's position at the moment this method is invoked; the index of the last byte written will be p + n - 1. Upon return the buffer's position will be equal to p + n; its limit will not have changed. Unless otherwise specified, a write operation will return only after writing all of the r requested bytes. Some types of channels, depending upon their state, may write only some of the bytes or possibly none at all. A socket channel in non-blocking mode, for example, cannot write any more bytes than are free in the socket's output buffer. 正常情况下,一个写操作会在全部数据写入后返回,但是在某些特殊的通道(Socket的非阻塞模式)中,因为缓冲区满,数据有可能部分写入或者没有写入 所以从这里来说,通道的写不是线程安全的,因为有可能想写入10B的数据,但是只写入了5B,那下次线程调度的时候,就有可能写乱数据 对于读,因为socket是流式的操作,我们虽然可以一次发送20个字节,但是同步的read()有可能只收到3个字节,剩下饿得17个字节还在传输,那么就有可能被另一个线程读到,数据就乱了 总结 1.因为读/写本身就是阻塞式的,同时只有一个线程可以操作,但是读/写都不是线程安全的,所以一般一个通道也都只有一个线程读,一个线程写,或者一个线程把读/写都做了 2.read和write方法并不一定会操作和ByteBuffer容量相等的数据,这两个方法会返回这期间操作的字节数,因此在应用端需要判断,如果仅仅进行部分传输,需要重新进行传输,使用hasReminding()方法判断是否还有数据 2 关于通道的关闭API说明上说 可以看出close操作是线程安全的,但是close操作本身是否会阻塞没有做明确说明,从其他地方看到应该没有特别说明的话,都是会阻塞的:
在通道关闭之后,正在进行的read或者write操作会收到一个AsynchronousCloseException |
|
来自: 碧海山城 > 《通道和NIO基础》