分享

nio通道(2)---几个注意点

 碧海山城 2012-08-22

这一篇的内容本来可以和上一篇写在一起,感觉特别重要,因此单独拿出来了

 

1          关于通道(Socket)读/写线程安全

 

下面是ReadableByteChannelWriteByteChannel接口的说明:

 

 Only one read/write operation upon a readable channel may be in progress at any given time. If one thread initiates a read/write operation upon a channel then any other thread that attempts to initiate another read operation will block until the first operation is complete. Whether or not other kinds of I/O operations may proceed concurrently with a read operation depends upon the type of the channel.

 

从这里来看,通道的读写好像是线程安全的,任何时候只有一个线程可以读,可以写,其他线程都要等待。

 

下面是两个接口的readwrite方法的说明

 

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.readwrite方法并不一定会操作和ByteBuffer容量相等的数据,这两个方法会返回这期间操作的字节数,因此在应用端需要判断,如果仅仅进行部分传输,需要重新进行传输,使用hasReminding()方法判断是否还有数据

 

2          关于通道的关闭

API说明上说

 This method may be invoked at any time. If some other thread has already invoked it, however, then another invocation will block until the first invocation is complete, after which it will return without effect.

 

可以看出close操作是线程安全的,但是close操作本身是否会阻塞没有做明确说明,从其他地方看到应该没有特别说明的话,都是会阻塞的:

 

 
 

在通道关闭之后,正在进行的read或者write操作会收到一个AsynchronousCloseException

  

 

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多